Modularizando o src

Dependencies:   EALib EthernetInterface_vz mbed-rtos mbed

Fork of header_main_colinas_V0-20-09-14 by VZTECH

main.cpp

Committer:
klauss
Date:
2014-12-30
Revision:
81:3656f00ab3db
Parent:
80:61d61c9eb75c
Child:
82:f55d13babca0

File content as of revision 81:3656f00ab3db:

#include "telemetry.h"                                                                                                                  
#include "eth.h"                                                                                                                        
#include "bits.h"                                                                                                                       
#include "UART3Interrupt.h" // for RXBuffer[ __CB_BUFFER_SIZE__ ];                                                                                 
#include "utils.h"                                                                                                                      
#include "parallelcpld.h"                                                                                                               
#include "debug.h"                                                                                                                      
#include "flood.h"                                                                                                                      
#include "bootloader_cbx.h"                                                                                                             
#include "call_manager.h"                                                                                                               
#include "call_box_manager.h"                                                                                                           
#include "sip_manager.h"                                                                                                                
#include "shared_variables.h"
#include "prompt.h"
#include "configs.h"

int main(){
    init_wdt();
    
    config_lpc();
    
    start_cpld();
    
    init_fsystem();
    
    short int eth_status = __init_eth__();
    if( eth_status ){
        send_msg("Cannot connect to eth\n\r");
    }else{
        send_msg("******* Connection eth - ok *******");
        init_prompt_eth();
    }
    
    Timer sync_timer, led_sync_timer;
    sync_timer.start(), led_sync_timer.start();
          
    /* representa ramal do call box */
    int ext = 0;
    
    /* representa porta do call box */
    int port = 0;
    
    /* buffer para onde se copia os dados vindos do cb para tratameno interno */
    uint8_t buffer[ __CB_BUFFER_SIZE__ ]; 
    
    /* buffer de escrita do pacote de saida que sera enviado pro cb / servidor */
    uint8_t write_buffer[ __CB_BUFFER_SIZE__ ];
    
    /* ponteiro que aponta para os dados vindo do CPLD */
    uint8_t * buffer_from_cb_ptr = ( uint8_t * )RXBuffer;
    
    /* Armazena o ultimo pacote recebido dos CBx */
    uint8_t cb_rx_buffer[ __CB_BUFFER_SIZE__ ];
    
    /* referencia para os dados contidos no pacote, sem o header */
    uint8_t * data = NULL;
    
    /* gerencia o tipo do pacote para providenciar tratamento adequado */
    volatile uint8_t type = __DO_NOTHING__;
    
    /* representa a lista dos Call Boxes atualmente reconhecidos pela cabeceira */
    Vector * v_cb = new Vector();
    
    /* representa a lista de ligacoes ativas na cabeceira */
    Vector * v_call = new Vector();
    
    /* gerencia a distribuicao de timeslice para os call boxes */
    Timeslice * ts = new Timeslice();
    
    /* instancia o vetor de call boxes // calls  */
    if( v_cb == NULL ){
        while( v_cb == NULL ){
            Vector * v_cb = new Vector();
            if( sync_timer.read() > 5 ){
                send_msg("Erro ao alocar o vetor de CBx");
                sync_timer.reset();
            }
        }
    }else if( v_call == NULL ){
        while( v_call == NULL ){
            Vector * v_call = new Vector();
            if( sync_timer.read() > 5 ){
                send_msg("Erro ao alocar o vetor de Calls");
                sync_timer.reset();
            }
        }
    }
    
    for( register uint16_t i = 0; i < __CB_BUFFER_SIZE__; i++ ){
        cb_rx_buffer[ i ] = 0;
        cb_tx_buffer[ i ] = 0;
    }
    
    reset_leds();
    
    udp_timer.start();
    
    init_telemetry_handler();
    
    init_ranges();
    
    init_refresh();
    
    init_aging();
    
    //init_invite_pgk_retry_manager();
    
    //void init_bye_pgk_retry_manager();
    static uint8_t count = 0;
    
    short int bl_ret = init_bl_handler();
    if( dbl ) send_msg("Valor de retorno do bl_habdler = %d", bl_ret );
    
    uint8_t max_registered_cbx = 0;
    
    bool wake_all = false;
    
    uint16_t pkg_wdt = RX_CB_IDLE;
    uint16_t eth_wdt = ETH_CONNECT_TIMEOUT;
    
    send_msg("Ready");
    
    /*------------------------------------------ main loop ---------------------------------------------------------------*/
    while( true ){
        if( v_cb->size() > max_registered_cbx ) max_registered_cbx = v_cb->size();
        
        if( sync_timer.read() > 5 ){
            sync_timer.reset();
            
            if( debug_cks == true ){
                pcks_s = true;
            }
            
            if( debug_alive == true ){
                pshowcb = true;
            }
                       
            if( !( ++count % 15 ) ){
                if( eth_status ){
                    eth_status = __init_eth__();
                    if( eth_status ){
                        if( debug_main ) debug_msg("Cannot connect to eth");
                    }else{
                        if( debug_main ) debug_msg("Connection eth - ok");
                        init_prompt_eth();
                    }
                }
            }
            //35 sec.
            if( ( count > 7 ) && ( wake_all == false ) ){
                wake_all = true;
                if( debug_wake == true ) send_msg( "Time to wake" );
            }
            
            if( wake_all ) if( v_call->size() == 0 ) wake_all_up( v_cb, buffer, write_buffer );
        }
        
        //FIXMEj colocar uma condicao aqui caso necessario pra nao comprometer ligacoes ...
        prompt_process( NULL );
        
        if( r_stats ){
            boot_counter = 0; 
            registry_counter = 0; 
            invite_counter = 0; 
            audio_counter = 0; 
            telemetry_counter = 0; 
            cb_bye_counter = 0; 
            prompt_counter = 0; 
            flood_counter = 0; 
            bootloader_cbx_counter = 0;
            r_stats = false;
            stats = true;
        }
        
        if( stats ){
            char str[ 200 ];
            snprintf( str, 200, "\n\rReceived Pkgs::\n\r Boot :: %u\n\r Registry :: %u\n\r Ivite :: %u\n\r Audio :: %u\n\r Telemetry :: %u\n\r Cb_bye :: %u\n\r Prompt :: %u\n\r Flood :: %u\n\r Bootloader_cbx :: %u\n\r", 
                boot_counter, registry_counter, invite_counter, audio_counter, telemetry_counter, cb_bye_counter, prompt_counter, flood_counter, bootloader_cbx_counter );
            send_msg( str );
            stats =false;
        }
        
        if( list ){
            uint8_t missed_cb = ( ( max_ext - min_ext ) + 1 ) - v_cb->size();
            
            if( ( max_ext % 2 ) == 0 ) missed_cb++;
            
            if( min_ext % 2 ) missed_cb++;
            
            if( min_ext == 0 && max_ext == 0 ) missed_cb = 0;
            
            send_msg("Registered %d[ %d ] CBx ( %d - %d ) - Missed %d -- Remain_timeslices :: %d :: v_call->size() :: %d", v_cb->size(), max_registered_cbx, min_ext, max_ext, missed_cb, ts->remain_timeslices(), v_call->size() );
            if( v_cb->size() == 1 ){
                send_msg(" %d ", ( ( Call_Box * )v_cb->get_element( 0 ) )->get_ext() );
            }else if( v_cb->size() > 1 ){
                char str[ 1024 ];
                int ext_list[ __MAX_CB_IN_A_BRANCH__ ];
                register int i = 0;
                for( ; i < v_cb->size(); i++ ){
                    ext_list[ i ] = ( ( Call_Box * )v_cb->get_element( i ) )->get_ext();
                }
                
                qsort( ext_list, v_cb->size(), sizeof( int ), ls_comp );
        
                char aux[ 16 ];
                strcpy( str, "\r\n> " );
                for( i = 0; i < v_cb->size() - 1; i++ ){
                    sprintf( aux, "%i, ", ext_list[ i ] );
                    strcat( str, aux );
                    if( ( i != 0 ) && !( ( i + 1 ) % 16 ) ) strcat( str, "\r\n> " );
                }
                sprintf( aux, "%i ", ext_list[ i ] );
                strcat( str, aux );
                send_msg( "%s", str );
            }
            list = false;    
        }
        
        if( long_list ){
            //FIXME implementar um algoritmo que me mostre o timeout de cada cbx do lado da linha, desse.
            uint8_t missed_cb = ( ( max_ext - min_ext ) + 1 ) - v_cb->size();
            
            if( ( max_ext % 2 ) == 0 ) missed_cb++;
            
            if( min_ext % 2 ) missed_cb++;
            
            if( min_ext == 0 && max_ext == 0 ) missed_cb = 0;
            
            send_msg("Registered %d[ %d ] CBx ( %d - %d ) - Missed %d -- Remain_timeslices :: %d :: v_call->size() :: %d", v_cb->size(), max_registered_cbx, min_ext, max_ext, missed_cb, ts->remain_timeslices(), v_call->size() );
            if( v_cb->size() == 1 ){
                send_msg(" %d ", ( ( Call_Box * )v_cb->get_element( 0 ) )->get_ext() );
            }else if( v_cb->size() > 1 ){
                char str[ 1024 ];
                int ext_list[ __MAX_CB_IN_A_BRANCH__ ];
                register int i = 0;
                for( ; i < ( v_cb->size() * 2 ); i += 2 ){
                    ext_list[ i ] = ( ( Call_Box * )v_cb->get_element( i ) )->get_ext();
                    ext_list[ i + 1 ] = ( ( Call_Box * )v_cb->get_element( i ) )->get_elapsed_time();
                }
                
                qsort( ext_list, v_cb->size(), sizeof( int ) * 2, ls_comp );
        
                char aux[ 16 ];
                strcpy( str, "\r\n> " );
                for( i = 0; i < ( v_cb->size() * 2 ) - 2; i++ ){
                    sprintf( aux, "%i - %i,", ext_list[ i ], ext_list[ i + 1 ] );
                    strcat( str, aux );
                    strcat( str, "\r\n> " );
                }
                sprintf( aux, "%i - %i,", ext_list[ i ], ext_list[ i + 1 ] );
                strcat( str, aux );
                send_msg( "%s", str );
            }
            list = false;    
        }
        
        if( pshowcb == true ){
            send_msg("Registered %d ( of %d ) CBx ( %d - %d ) -- Remain_timeslices :: %d :: v_call->size() :: %d", v_cb->size(), max_registered_cbx, min_ext, max_ext, ts->remain_timeslices(), v_call->size() );
            for( register uint8_t i = 0; i < v_cb->size(); i++ ){
                Call_Box * cb = ( Call_Box * )v_cb->get_element( i );
                char cb_status[ 32 ];
                char cb_sip_status[ 32 ];
                switch( cb->status ){
                    case cb_idle : { strcpy( cb_status, "cb_idle" ); break; }
                    case cb_ringing : { strcpy( cb_status, "cb_ringing" ); break; }
                    case cb_trying : { strcpy( cb_status,"cb_trying" ); break; }
                    case cb_on_call : { strcpy( cb_status, "cb_on_call" ); break; }
                    case cb_busy : { strcpy( cb_status, "cb_busy" ); break; }
                    case cb_denied : { strcpy( cb_status, "cb_denied" ); break; }
                }
                switch( cb->sip->status ){
                    case sip_idle : { strcpy( cb_sip_status, "sip_idle" ); break; }
                    case sip_waiting_trying : { strcpy( cb_sip_status, "sip_waiting_trying" ); break; }
                    case sip_trying : { strcpy( cb_sip_status, "sip_trying" ); break; }
                    case sip_ringing : { strcpy( cb_sip_status, "sip_ringing" ); break; }
                    case sip_busy : { strcpy( cb_sip_status, "sip_busy" ); break; }
                    case sip_ok : { strcpy( cb_sip_status, "sip_ok" ); break; }
                    case sip_on_call : { strcpy( cb_sip_status, "sip_on_call" ); break; }
                    case sip_denied : { strcpy( cb_sip_status, "sip_denied" ); break; }
                }
                char cbx_to_string[ 254 ];
                char aux[ 16 ];
                strcpy( cbx_to_string, "Ext :: " );
                itoa( cb->get_ext(), aux , 10 );
                strcat( cbx_to_string, aux );
                strcat( cbx_to_string, " :: Status -- " );
                strcat( cbx_to_string, cb_status );
                strcat( cbx_to_string, " - " );
                strcat( cbx_to_string, cb_sip_status );
                if( cb->get_timeslice() != 0 ){
                    strcat( cbx_to_string, " -- on TimeSlice :: " );
                    itoa( cb->get_timeslice(), aux , 10 );
                    strcat( cbx_to_string, aux );
                }
                send_msg( cbx_to_string );
            }
            pshowcb = false;
        }
        
        if( pflood == true ) flood();
        
        if( debug_eth ){
            debug_eth = false;
            send_msg("Eth status %s", ( eth_status == 0 ) ? "Connected" : "Disconnected" );
        }
        
        if( status != __WAITING__ ){
            pkg_wdt = RX_CB_IDLE;
            xmemcpy( cb_rx_buffer, buffer_from_cb_ptr, __CB_BUFFER_SIZE__ );    
            status = __WAITING__;
            missed_pkg--;
            xmemcpy( buffer, cb_rx_buffer, __CB_BUFFER_SIZE__ );    
            
            if( debug_cpld ){ 
                rx = true;
                tx = true;
            }
            
            if( rx ){
                char str[ 1024 ];
                strcpy( str, "RX :: \n\r " );
                for( register uint16_t i = 0; i < __CB_BUFFER_SIZE__; i++ ){
                    char tmp[ 16 ];
                    strcat( str, itoa( cb_rx_buffer[ i ], tmp, 16 ) );
                    if( ( i != 0 ) && !( ( i + 1 ) % 50 ) ) strcat( str, "\n\r " );
                    
                    else strcat( str, " " );
                }
                send_msg( "%s", str );
                rx = false;    
            }
                
            data = __parse_vz_pkg__( &ext, &port, &type, buffer );
            
            if( data != NULL ){
                if( min_ext == 0 ) min_ext = ext;
            
                if( ext > max_ext ) max_ext = ext;
                
                if( ext < min_ext ) min_ext = ext;
                
                if( debug_cb_rx == true ) debug_msg("Pkg from CBx :: %d -- Type :: %d", ext, type );
                
                if( type != __AUDIO__ ){
                    Call_Box * cb = __find_CB__( v_cb, ext );
                    if( cb != NULL ){
                        if( ( data[ 0 ] & BIT7 ) >= BIT7 ){ 
                            if( type == __BOOT__ ){ 
                                send2callboxes( __build_cb_package__( ext, port, __REGISTRY__, 
                                    ( char * )data, cb->get_msg_id(), __CB_BUFFER_SIZE__ - __VZ_HEADER_OFFSET__, write_buffer ) );
                            }else if( ( data[ 0 ] & BIT7 ) == BIT7 ){
                                if( debug_main ) debug_msg("Received ack pkg with seq_num %d", data[ 0 ] );
                                //algum motivo pra sempre receber alguma coisa com o type == 7 ???
                                if( type == 0x07 ){
                                    char str[ 1024 ];
                                    strcpy( str, "RX :: \n\r " );
                                    for( register uint16_t i = 0; i < __CB_BUFFER_SIZE__; i++ ){
                                        char tmp[ 16 ];
                                        strcat( str, itoa( cb_rx_buffer[ i ], tmp, 16 ) );
                                        if( ( i != 0 ) && !( ( i + 1 ) % 50 ) ) strcat( str, "\n\r " );
                                        
                                        else strcat( str, " " );
                                    }
                                    send_msg( "%s", str );
                                    rx = false;    
                                }                
                                switch( type ){
                                    case __INVITE__ : {
                                        if( debug_main || debug_invite ) debug_msg("Invite Ack from %d on msg_id %d", ext, cb->get_msg_id() );
                                        cb->set_invite_response_ok();
                                        break;    
                                    }
                                    case __CB_BYE__ : {
                                        if( debug_main || debug_invite ) debug_msg("BYE Ack from %d on msg_id %d", ext, cb->get_msg_id() );
                                        cb->set_bye_response_ok();
                                        break;    
                                    }
                                    case __REGISTRY__ : {
                                        if( debug_main || debug_aging ) debug_msg("Registry ACK from %d in pkg :: %d", ext, cb->get_msg_id() );
                                        break;
                                    }
                                    default : {
                                        if( debug_main || debug_aging ) debug_msg("ACK from %d in pkg :: %d :: type %d", ext, cb->get_msg_id(), type );   
                                    }    
                                }
                                if( type != __REGISTRY__ ) type = __DO_NOTHING__;
                            }
                        }
                    }
                }
            }else type = __DO_NOTHING__;
        }
        
        if( main_test == true ){
         //   Call_Box * cb = new Call_Box( 5010, 5010 );
         //   v_cb->add( cb );
         //   cb = new Call_Box( 5011, 5011 );
         //   v_cb->add( cb );
            main_test = false;
            send_msg("Missed_Pkg :: %d ::", missed_pkg );
        }
        
        if( reset_cks == true ){
            pkg_cksok = 0;
            pkg_ckserr = 0;
            reset_cks = false;
            pcks_s = true;
        }
        
        if( pcks_s == true ){
            send_msg("PKG_CSK OK: %d :: PKG_CSK ERR: %d :: PKG_ZERO: %d :: Out_of_range: %d :: Missed_Pkg :: %d", pkg_cksok, pkg_ckserr, pkg_zero, out_of_range, missed_pkg );
            pcks_s = false;
        }
        
        if( led_sync_timer.read() > 1 ){
            led_sync_timer.reset();
            led3 = !led3;
            CAB_LED = !CAB_LED;
        }
        
        switch( type ){
            case __DO_NOTHING__ :{}
                break;
                
            case __CB_BYE__ : {
                //FIXME como mandar um BYE pro servidor ?
                cb_bye_counter++;
                Call_Box * cb = __find_CB__( v_cb, ext );
                if( cb != NULL ){
                    if( debug_invite || debug_main ) debug_msg("Received bye pkg with msg_id %d e pkg_id %d", cb->get_msg_id(), data[ 0 ] );
                    data[ 0 ] |= BIT7;
                    cb->set_msg_id( data[ 0 ] );
                    if( debug_main || debug_invite ) debug_msg( "Request bye from CBx " );
                    bool already_removed = true;
                    for( register uint8_t i = 0; i < v_call->size(); i++ ){
                        VZ_call * call = (VZ_call *)v_call->get_element( i );
                        if( call->get_cb_ext() == ext ){
                            already_removed = false;
                            cb->send_bye();
                            
                            ts->return_timeslice( cb->get_timeslice() );
                            cb->set_timeslice( 0x00 );
                            data[ __TIMESLICE_PLACE__ ] = 0x00;
                            
                            set_status( cb->status, cb_idle );
                            set_status( cb->sip->status, sip_idle );
                            
                            v_call->remove_element( i );
                            
                            cb->set_msg_id( ( cb->get_msg_id() &  ~BIT7 ) + 1 );
                            
                            send2callboxes( __build_cb_package__( ext, port, __CB_BYE__,
                                ( char * )data, cb->get_msg_id(), __CB_BUFFER_SIZE__ - __VZ_HEADER_OFFSET__, write_buffer ) );
                            
                            delete( call );
                            cb->re_start_timer();
                        }
                    }
                    if( already_removed ) if( debug_main || debug_invite ) debug_msg( "Already removed" );
                    
                    cb->registry();
                }else if( debug_invite || debug_main ) debug_msg("Bye from who ? %d", ext );
            }break;
            
            case __INVITE__ : {
                invite_counter++;
                if( debug_invite ) debug_msg("Request Invite received from Cbx %i", ext);
                Call_Box * cb = __find_CB__( v_cb, ext );
                if( cb == NULL ){
                    if( debug_main ) debug_msg( "Adding CBx :: %i", ext );
                    cb = new Call_Box( ext, port );
                    v_cb->add( cb );
                }
                cb->registry();
                cb->set_msg_id( data[ 0 ] );    
                invite_handler( v_call, v_cb, ts, cb );
            }break;
            case __REGISTRY__ : {
                registry_counter++;
                Call_Box * cb = __find_CB__( v_cb, ext );
                
                if( cb == NULL ){
                    if( debug_main ) debug_msg("Adding Cbx :: %d", ext );
                    cb = new Call_Box( ext, port );
                    v_cb->add( cb );
                    if( debug_main ) debug_msg("Added CBx -- %d", ext );
                }
                if( debug_main ) debug_msg("Registered %d - %d", ext, port );
                    
                cb->registry();
                
                }break;
            case __BOOT__ : {
                boot_counter++;
                send2callboxes( __build_cb_package__( ext, port, __REGISTRY__, 
                    ( char * )data, data[ 0 ] | BIT7, __CB_BUFFER_SIZE__ - __VZ_HEADER_OFFSET__, write_buffer ) );
                }break;
            case __TELEMETRY__ : {
                Call_Box * cb = __find_CB__( v_cb, ext );
                if( cb == NULL ){
                    if( debug_main ) debug_msg("Adding Cbx :: %d", ext );
                    cb = new Call_Box( ext, port );
                    v_cb->add( cb );
                    if( debug_main ) debug_msg("Added CBx -- %d", ext );
                }
                cb->registry();
                //FIXME mandar um pacote do tipo 2 pro cbx precis
                telemetry_counter++;
                if( debug_telemetry ) send_msg("::Telemetry from %d - %d::", ext, port );
                    build_telemetry_report( ext, port, ( char *)data );
                }break;
                
            case __BOOTLOADER_CBX__ : {
                bootloader_cbx_counter++;
                int ret = bl_cbx_reply_to_eth( ext, ( char * )data );
                }break;
                
            case __PROMPT__ : {
                Call_Box * cb = __find_CB__( v_cb, ext );
                if( cb == NULL ){
                    if( debug_main ) debug_msg("Adding Cbx :: %d", ext );
                    cb = new Call_Box( ext, port );
                    v_cb->add( cb );
                    if( debug_main ) debug_msg("Added CBx -- %d", ext );
                }
                
                cb->registry();
                
                if( xstrmatch( ( uint8_t * )data, ( uint8_t * )"ping" ) ){
                    if( debug_ping ) send_msg( "Prompt pkg from ( %i, %i ) :: Ping", ext, port );
                }else{
                    prompt_counter++;
                    //fixme isso nao poderia ser resolvido com um sendmsg ?
                    send_msg( "Prompt pkg from ( %i, %i ) ::", ext, port );
                    for( register uint8_t i = 0; i < 32; i++ ){
                        pc.printf("%c", data[ i ] );
                        if( i == 15 ) pc.printf( "\r\n" );
                    }
                    pc.printf("\n\r> ");
                    
                    if( tcp_session ){
                        char aux[ __CB_BUFFER_SIZE__ + 3 ];
                        strncpy( aux, (char * )data, __CB_BUFFER_SIZE__ );
                        strcat( aux, "\n\r\0" );
                        tcp_client.send_all( ( char *)data, strlen( (char * )data ) );
                        tcp_client.send_all( "\r\n> ", strlen( "\r\n> " ) );
                    }
                }
                }break;
            case __AUDIO__ : {
                audio_counter++;
                VZ_call * call = __find_Call__( v_call, ext );
                if( call != NULL ){
                    char * pkg = call->build_eth_package( data + 2 ); 
                    call->send_message( pkg );
                    Call_Box * cb = __find_CB__( v_cb, ext );
                    if( cb != NULL ) cb->reset_elapsed_time();
                }else{
                    if( debug_main ) debug_msg("received missed package  from CBx :: %i", ext );
                }
            }break;
        }// fim switch
        
        for( register uint8_t i = 0; i < v_call->size(); i++ ){
            VZ_call * call = ( VZ_call * )v_call->get_element( i );
            int length = 0;
            char * tmp = call->get_eth_message( &length );
            if( tmp != NULL ){
                int cb_port = 0xffff;
                Call_Box * cb = __find_CB__( v_cb, call->get_cb_ext() );
                
                if( cb != NULL ){
                    cb_port = cb->get_port();
                    
                    uint8_t * pkg2cb = __build_cb_package__( call->get_cb_ext(), cb_port, __AUDIO__, 
                    tmp, __AUDIO__, length, write_buffer );
                
                    send2callboxes( pkg2cb );
                }else if( debug_main ) debug_msg("received missed package  from CBx :: %i -- Type :: %i", ext, type );
            }
        }
        //if( v_call->size() == 0 ) refresh( v_cb, buffer, write_buffer, NULL );
        refresh( v_cb, buffer, write_buffer, NULL );
        
        //Fixme pensar melhor nessa parte durante ligacoes, pode complicar com muitos cbx ...
        //if( v_call->size() == 0 ) registry_aging( v_cb, buffer, write_buffer );
        
        // check sip messages only for cbx in call ?
        int ext_to__be_removed = sip_manager( v_cb );
        if( ext_to__be_removed > 0x00 ){
            Call_Box * cb = __find_CB__( v_cb, ext_to__be_removed );
            if( cb != NULL ){
                if( cb->status == cb_on_call ){
                    ts->return_timeslice( cb->get_timeslice() );
                    cb->set_timeslice( 0x00 );
                    buffer[ __TIMESLICE_PLACE__ ] = 0x00;
                    
                    set_status( cb->status, cb_idle );
                    set_status( cb->sip->status, sip_idle );
            
                    for( register uint8_t i = 0; i < v_call->size(); i++ ){
                        VZ_call * call = ( VZ_call * )v_call->get_element( i );
                        if( call->get_cb_ext() == ext_to__be_removed ){
                            v_call->remove_element( i );
                            delete( call );
                        }
                    }
            
                    //cb->set_msg_id( ( cb->get_msg_id() &  ~BIT7 ) + 1 );
                    cb->set_msg_id( 80 );
                    
                    debug_msg("msg_id -- %d", cb->get_msg_id() );
                    
                    send2callboxes( __build_cb_package__( ext, port, __CB_BYE__, 
                        ( char * )buffer, cb->get_msg_id(), __CB_BUFFER_SIZE__ - __VZ_HEADER_OFFSET__, write_buffer ) );
            
                    //cb->re_start_timer();
                }
            }else if( debug_main ) debug_msg("Missed bye request from * CBx :: %d", ext );
        }
        
        /* Verifica andamento de ligações para eventualmente encerra-las por timeout */
        call_manager( v_call, v_cb, buffer, write_buffer, ts );
        
        /* tratamento de pedidos de ligação */
        invite_handler( v_call, v_cb, ts, NULL );
        
        /* rotina de verificação de TS's perdidos */
        if( ( v_call->size() == 0 ) && ( ts->remain_timeslices() != __MAX_TIMESLICES__ ) ){
             bool ts_reset = true;
             for( register uint8_t i = 0; i < v_cb->size(); i++ ){
                if ( ( ( Call_Box * )v_cb->get_element( i ) )->get_status() != cb_idle ){
                    ts_reset = false;
                    break;
                }
            }   
            if( ts_reset ){
                if( debug_invite ) debug_msg("Resetando TS");
                ts->reset();
            }
        }
        
        //invite_pgk_retry_manager( v_call, v_cb, buffer, write_buffer );
        
        /* escuta se existe algum procedimento de gravação de cbx */
        bl_handler();
        
        /* rotina que esvazia possiveis pacotes que não foram transmitidos para evitar conflito */
        tx_buffer_ring_buffer_handler();
        
        type = __DO_NOTHING__;
        
        if( eth_status == 0 ) eth_wdt = ETH_CONNECT_TIMEOUT;
        
        if( wdt_timer.read() > 1 ){
            wdt_timer.reset();
            
            if( wdt_show ) debug_wdt = true;
            
            if( external_wdt ) external_wdt--;
            if( pkg_wdt ) pkg_wdt--;
            if( eth_wdt ) eth_wdt--;
            
            if( eth_wdt && external_wdt && pkg_wdt ){
                wdt.kick();
            }
        }
        
        if( debug_wdt ){
            debug_wdt = false;
            if( eth_status == 0 ){
                send_msg( "Wdt last reset: %s - status_eth :: Connected - Extern Wdt idle for :: %3d sec - Rx from CBx idle for :: %3d sec", 
                    ( wdt.WatchdogCausedReset() ) ? "true" : "false", 
                    EXTERN_WDT_IDLE - external_wdt, 
                    RX_CB_IDLE - pkg_wdt 
                );
            }else{
                send_msg( "Wdt last reset: %s - status_eth :: Disconnected :: since %3d sec - Extern Wdt idle for :: %3d sec - Rx from CBx idle for :: %3d sec", 
                    ( wdt.WatchdogCausedReset() ) ? "true" : "false", 
                    ETH_CONNECT_TIMEOUT - eth_wdt,
                    EXTERN_WDT_IDLE - external_wdt, 
                    RX_CB_IDLE - pkg_wdt 
                );
            }
        }
    }
}