static void s_overridden_appl_initialise_services(void)
{    
    eOipv4addr_t ipaddress = eom_ipnet_GetIPaddress(eom_ipnet_GetHandle());
    // if we want to use another board ... uncomment the following for board 10.0.1.2 ... or change to other address.
    // ipaddress = eo_common_ipv4addr(10, 0, 1, 2);

    // initialise services ...
    eo_services_Initialise(ipaddress);
    
    // and start them on the basis of the boardnumber 
    // ..... DONT DO IT ANYMORE because now we use runtime configuration.
    // eo_services_Start(eo_services_GetHandle());
}
extern EOMtheEMSdiscoverylistener * eom_emsdiscoverylistener_Initialise(const eOemsdiscoverylistener_cfg_t *cfg)
{
    if(NULL != s_emsdiscoverylistener_singleton.task)
    {
        return(&s_emsdiscoverylistener_singleton);
    }
    
    if(NULL == cfg)
    {
        cfg = &eom_emsdiscoverylistener_DefaultCfg;
    }
    
    memcpy(&s_emsdiscoverylistener_singleton.cfg, cfg, sizeof(eOemsdiscoverylistener_cfg_t));
    
    
    if(NULL == eom_ipnet_GetHandle())
    {
        eo_errman_Error(eo_errman_GetHandle(), eo_errortype_fatal, "eom_emsdiscoverylistener_Initialise(): EOMtheIPnet not started yet", s_eobj_ownname, &eo_errman_DescrRuntimeErrorLocal);
    }

    // create the socket    
    s_emsdiscoverylistener_singleton.socket = eo_socketdtg_New(cfg->inpdatagramnumber, cfg->inpdatagramsizeof, (eobool_true == cfg->usemutex) ? (eom_mutex_New()) : (NULL), 
                                                               cfg->outdatagramnumber, cfg->outdatagramsizeof, (eobool_true == cfg->usemutex) ? (eom_mutex_New()) : (NULL)
                                                              );    
    // create the rx packet
    s_emsdiscoverylistener_singleton.rxpkt = eo_packet_New(cfg->inpdatagramsizeof);
    
    
    // initialise the transceiver
    eOemsdiscoverytransceiver_cfg_t dtrcfg;
    dtrcfg.hostipv4addr  = cfg->remoteipaddr;
    dtrcfg.hostipv4port  = cfg->remoteport;
    dtrcfg.txpktcapacity = cfg->outdatagramsizeof;
    dtrcfg.discoveryprotocol = cfg->discoveryprotocol;
    dtrcfg.dbgshutdowntime = 0; // if 0 the shutdown timer is not started. otherwise it forces a got to updater. 3*60*eok_reltime1sec;
    eom_emsdiscoverytransceiver_Initialise(&dtrcfg);
    
    
    // create the task
    s_emsdiscoverylistener_singleton.task = eom_task_New(eom_mtask_EventDriven, cfg->taskpriority, cfg->taskstacksize, 
                                                    s_eom_emsdiscoverylistener_task_startup, s_eom_emsdiscoverylistener_task_run,  
                                                    (eOevent_t)0, eok_reltimeINFINITE, NULL, 
                                                    tskEMScfg, "tskEMSlis");
 
                                                   
    
    return(&s_emsdiscoverylistener_singleton);
}
extern eOresult_t eo_theEMSdgn_UpdateApplCore(EOTheEMSdiagnostics_t* p)
{

//core
    eOemsrunner_diagnosticsinfo_t* dgn_run_ptr =  eom_emsrunner_GetDiagnosticsInfoHandle(eom_emsrunner_GetHandle());
    if(NULL != dgn_run_ptr)
    {    
        eo_dgn_emsapplcore.core.runst.numberofperiods = dgn_run_ptr->numberofperiods;
        eo_dgn_emsapplcore.core.runst.cumulativeabsoluteerrorinperiod = dgn_run_ptr->cumulativeabsoluteerrorinperiod;
        eo_dgn_emsapplcore.core.runst.meanofabsoluteerrorinperiod = dgn_run_ptr->meanofabsoluteerrorinperiod;
        eo_dgn_emsapplcore.core.runst.movingmeanofabsoluteerrorinperiod = dgn_run_ptr->movingmeanofabsoluteerrorinperiod;
        eo_dgn_emsapplcore.core.runst.maxabsoluteerrorinperiod = dgn_run_ptr->maxabsoluteerrorinperiod;
        eo_dgn_emsapplcore.core.runst.minabsoluteerrorinperiod = dgn_run_ptr->minabsoluteerrorinperiod;
        eo_dgn_emsapplcore.core.runst.executionoverflows[0] = dgn_run_ptr->executionoverflows[0];
        eo_dgn_emsapplcore.core.runst.executionoverflows[1] = dgn_run_ptr->executionoverflows[1];
        eo_dgn_emsapplcore.core.runst.executionoverflows[2] = dgn_run_ptr->executionoverflows[2];
        eo_dgn_emsapplcore.core.runst.datagrams_failed_to_go_in_txsocket = dgn_run_ptr->datagrams_failed_to_go_in_txsocket;
    }
    
//ipnet
    eOmipnet_diagnosticsinfo_t *dgn_ipnet_ptr = eom_ipnet_GetDiagnosticsInfoHandle(eom_ipnet_GetHandle());
    if(NULL != dgn_ipnet_ptr)
    {  
        eo_dgn_emsapplcore.ipnet.datagrams_failed_to_go_in_rxfifo = dgn_ipnet_ptr->datagrams_failed_to_go_in_rxfifo;
        eo_dgn_emsapplcore.ipnet.datagrams_failed_to_go_in_txosalqueue = dgn_ipnet_ptr->datagrams_failed_to_go_in_txosalqueue;
        eo_dgn_emsapplcore.ipnet.datagrams_failed_to_be_retrieved_from_txfifo = dgn_ipnet_ptr->datagrams_failed_to_be_retrieved_from_txfifo;
        eo_dgn_emsapplcore.ipnet.datagrams_failed_to_be_sent_by_ipal = dgn_ipnet_ptr->datagrams_failed_to_be_sent_by_ipal;  
    }
//transceiver
    eOemstransceiver_diagnosticsinfo_t* dgn_tr_ptr = eom_emstransceiver_GetDiagnosticsInfoHandle(eom_emstransceiver_GetHandle());
    if(NULL != dgn_tr_ptr)
    {  
        eo_dgn_emsapplcore.transceiver.rxinvalidropframes = dgn_tr_ptr->rxinvalidropframes;
        eo_dgn_emsapplcore.transceiver.rxseqnumwrong = dgn_tr_ptr->rxseqnumwrong;
        eo_dgn_emsapplcore.transceiver.lostreplies = dgn_tr_ptr->lostreplies;
        eo_dgn_emsapplcore.transceiver.failuresinloadofreplyropframe = dgn_tr_ptr->failuresinloadofreplyropframe;
        eo_dgn_emsapplcore.transceiver.txropframeistoobigforthepacket = dgn_tr_ptr->txropframeistoobigforthepacket;
        eo_dgn_emsapplcore.transceiver.cannotloadropinregulars = dgn_tr_ptr->cannotloadropinregulars;
        eo_dgn_emsapplcore.transceiver.cannotloadropinoccasionals = dgn_tr_ptr->cannotloadropinoccasionals;
    }
    
    return(eores_OK);
}
static eOresult_t s_eom_emsdiscoverylistener_Connect(EOMtheEMSdiscoverylistener* p, eOipv4addr_t remaddr)
{
    eOresult_t res = eores_OK;
    

    if((eobool_false == p->connected2host) || (remaddr != p->hostaddress))
    {
        p->connected2host = eobool_false;
        p->hostaddress    = remaddr;
        
        res = eom_ipnet_ResolveIP(eom_ipnet_GetHandle(), remaddr, 5*EOK_reltime1sec);
 
        if(eores_OK != res)
        {
            return(res);
        }
        p->connected2host = eobool_true;        
    }
    
    return(eores_OK);   
}
extern void eom_emstransceiver_callback_incaseoferror_in_sequencenumberReceived(EOreceiver *receiver)
{   // the only reason of using the following two variables as static is: to reduce the use of stack.
    static int64_t delta = 0;
    static eOerrmanDescriptor_t errdes = 
    {
        .code           = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_error),
        .sourcedevice   = eo_errman_sourcedevice_localboard,
        .sourceaddress  = 0,
        .par16          = 0,
        .par64          = 0
    };
    
    const eOreceiver_seqnum_error_t *err = eo_receiver_GetSequenceNumberError(receiver); 
    
    if(NULL == err)
    {
        errdes.code  = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_runtimeerror);
        errdes.par64 = 0x123467fabc222;
        errdes.par16 = 1;       
        eo_errman_Error(eo_errman_GetHandle(), eo_errortype_warning, NULL, NULL, &errdes);   
        return;        
    }
    
    if(1 == err->rec_seqnum)
    {
        // it is the first packet received from a remote transmitter freshly initted (i.e., robotInterface has just re-started bu this board was alive well before)
        // thus, we dont issue an error but an info: 
        errdes.code  = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_restarted);
        errdes.par64 = err->exp_seqnum;
        errdes.par16 = 1;       
        eo_errman_Error(eo_errman_GetHandle(), eo_errortype_info, NULL, NULL, &errdes);   
        
        // ok, now we must set back the error code as it is normal.
        errdes.code = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_error);
    }  
    else
    {    
        delta = err->rec_seqnum - err->exp_seqnum;
        if(delta > INT16_MAX)       delta = INT16_MAX;  //32767
        else if(delta < INT16_MIN)  delta = INT16_MIN;  //-32768;
        
        errdes.code             = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxseqnumber_error);
        errdes.par16            = (int16_t)delta; 
        errdes.par64            = err->exp_seqnum; 
        eo_errman_Error(eo_errman_GetHandle(), eo_errortype_error, NULL, NULL, &errdes);
    }
}


extern void eom_emstransceiver_callback_incaseoferror_invalidframe(EOreceiver *receiver)
{  
    static eOerrmanDescriptor_t errdesinvframe = 
    {
        .code           = EOERRORCODE(eoerror_category_System, eoerror_value_SYS_transceiver_rxinvalidframe_error),
        .sourcedevice   = eo_errman_sourcedevice_localboard,
        .sourceaddress  = 0,
        .par16          = 0,
        .par64          = 0
    };

    eo_errman_Error(eo_errman_GetHandle(), eo_errortype_error, NULL, NULL, &errdesinvframe);
}


// --------------------------------------------------------------------------------------------------------------------
// - definition of extern hidden functions 
// --------------------------------------------------------------------------------------------------------------------




// --------------------------------------------------------------------------------------------------------------------
// - definition of static functions 
// --------------------------------------------------------------------------------------------------------------------


/** @fn         static void s_eom_emsappl_main_init(void)
    @brief      It initialises the emsappl 
    @details    bla bla bla.
 **/

static void s_eom_emsappl_main_init(void)
{      
    // init leds via the EOtheLEDpulser object
    eOledpulser_cfg_t ledpulsercfg =  
    {
        .led_enable_mask    = (1 << eo_ledpulser_led_zero | 1 << eo_ledpulser_led_one | 1 << eo_ledpulser_led_two | 1 << eo_ledpulser_led_three | 1 << eo_ledpulser_led_four | 1 << eo_ledpulser_led_five),
        .led_init           = (eOint8_fp_uint8_cvoidp_t) hal_led_init,
        .led_on             = (eOint8_fp_uint8_t) hal_led_on,
        .led_off            = (eOint8_fp_uint8_t) hal_led_off,
        .led_toggle         = (eOint8_fp_uint8_t) hal_led_toggle
    };

    eo_ledpulser_Initialise(&ledpulsercfg);
    
    
    // init the ems application
    EOMtheEMSapplCfg* emscfg = eom_emsapplcfg_GetHandle();    
    eom_emsappl_Initialise(&emscfg->applcfg);
      
    // set the led reserved for link
    if(eores_OK == eom_ipnet_ResolveIP(eom_ipnet_GetHandle(), emscfg->applcfg.hostipv4addr, 5*EOK_reltime100ms))
    {
        // set led0 to ON
       eo_ledpulser_On(eo_ledpulser_GetHandle(), eo_ledpulser_led_zero);
    }
    else
    {
        eo_ledpulser_Off(eo_ledpulser_GetHandle(), eo_ledpulser_led_zero);
    }
}
extern void eom_emsappl_hid_userdef_initialise(EOMtheEMSappl* p)
{  
    EOMtheEMSapplCfg* emsapplcfg = eom_emsapplcfg_GetHandle();
    // the led-pulser is initted as first thing
     
    // pulse led3 forever at 20 hz.
    eo_ledpulser_Start(eo_ledpulser_GetHandle(), eo_ledpulser_led_three, EOK_reltime1sec/20, 0);
    
    {   // board number is from IP address
        s_boardnum = 0;
        eOipv4addr_t ipaddress = eom_ipnet_GetIPaddress(eom_ipnet_GetHandle());
        s_boardnum = ipaddress >> 24;  
        s_boardnum --;
        if(s_boardnum > 16)
        {
            //return;
            s_boardnum = 0;
        }
        
        //s_boardnum = 0; //it imposes that the board is the eb1
    }
    
    {   // CAN-MAPPING
        // marco.accame on 19 may 2015: here we load the map of can ... and also we map the entities into some can boards
        // ... if we have any.
        EOtheCANmapping * canmap = eo_canmap_Initialise(NULL);
        // now i load the map of can boards
        EOconstvector *canboards = eoboardconfig_code2canboards(s_boardnum);
        eo_canmap_LoadBoards(canmap, canboards);
        // now i load mc-joints, mc-motors, as-strain, as-mais, sk-skin
        EOconstvector *entitydes = NULL;
        // mc
        entitydes = eoboardconfig_code2entitydescriptors(s_boardnum, eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint);
        eo_canmap_ConfigEntity(canmap, eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, entitydes);
        entitydes = eoboardconfig_code2entitydescriptors(s_boardnum, eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor);
        eo_canmap_ConfigEntity(canmap, eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, entitydes); 
        // as
        entitydes = eoboardconfig_code2entitydescriptors(s_boardnum, eoprot_endpoint_analogsensors, eoprot_entity_as_strain);
        eo_canmap_ConfigEntity(canmap, eoprot_endpoint_analogsensors, eoprot_entity_as_strain, entitydes);
        entitydes = eoboardconfig_code2entitydescriptors(s_boardnum, eoprot_endpoint_analogsensors, eoprot_entity_as_mais);
        eo_canmap_ConfigEntity(canmap, eoprot_endpoint_analogsensors, eoprot_entity_as_mais, entitydes);
        // sk
        entitydes = eoboardconfig_code2entitydescriptors(s_boardnum, eoprot_endpoint_skin, eoprot_entity_sk_skin);
        eo_canmap_ConfigEntity(canmap, eoprot_endpoint_skin, eoprot_entity_sk_skin, entitydes);      
    }
    
    {   // CAN-PROTOCOL
        EOtheCANprotocol * canprot = eo_canprot_Initialise(NULL);              
    }


    {   // ETH-PROTOCOL   
        // marco.accame on 24 apr 2015: here is how to customise the eth protocol from a generic to a specific board
        // so far, we can keep it in here. but further on we shall customise one endpoint at a time in runtime.
        
        EOnvSet* nvset = eom_emstransceiver_GetNVset(eom_emstransceiver_GetHandle()); 
        uint8_t i = 0;
        // 1. set the board number. the value of the generic board is 99. 
        //    the correct value is used only for retrieving it later on and perform specific actions based on the board number
        eo_nvset_BRDlocalsetnumber(nvset, s_boardnum);
        
        EOconstvector* epcfg_cvector = eoboardconfig_code2EPcfg(s_boardnum);
        
        // 2. load all the endpoints specific to this board. the generic board loads only management
        uint16_t numofepcfgs = eo_constvector_Size(epcfg_cvector);
        for(i=0; i<numofepcfgs; i++)
        {
            eOprot_EPcfg_t* epcfg = (eOprot_EPcfg_t*) eo_constvector_At(epcfg_cvector, i);
            if(eobool_true == eoprot_EPcfg_isvalid(epcfg))
            {
                eo_nvset_LoadEP(nvset, epcfg, eobool_true);
            }                        
        }
        
        // now we must define the .... proxy rules
        // if we have board number equal to 1 or 3 ... (eb2 or eb4) then we set it for mc only
        eOprotBRD_t localboard = eoprot_board_local_get();
        if((1 == localboard) || (3 == localboard))
        {
            eoprot_config_proxied_variables(eoprot_board_localboard, eoprot_endpoint_motioncontrol, eoprot_b02_b04_mc_isproxied);
        }
    }    
        
    
    // start the application body   
    eOemsapplbody_cfg_t applbodyconfig;
    
    memcpy(&applbodyconfig, &theemsapplbodycfg, sizeof(eOemsapplbody_cfg_t));
    
    // now i get the encoder config
    
    const eOappEncReader_cfg_t *enccfg = eoboardconfig_code2encoderconfig(s_boardnum);
    memcpy(&applbodyconfig.encoderreaderconfig, enccfg, sizeof(eOappEncReader_cfg_t)); 
    
    eo_emsapplBody_Initialise(&applbodyconfig);       
}