Modularizando o src

Dependencies:   EALib EthernetInterface_vz mbed-rtos mbed

Fork of header_main_colinas_V0-20-09-14 by VZTECH

sip.cpp

Committer:
klauss
Date:
2015-05-13
Revision:
125:8ff4dc96ad58
Parent:
124:c1b6c893e1c3
Child:
132:05cd37f7e007

File content as of revision 125:8ff4dc96ad58:

#include "sip.h"

//*[ begin ] ------------------------------------ Funcoes de uso interno ---------------------------------------------- *//
void Sip::__init_sock__ ( void )
{
    sip_server.set_address ( this->server_ip , this->server_port );
    sock.set_blocking ( false, 0 );
    sock.bind ( this->my_port );
}

void Sip::__end_sock__ ( void )
{
    sock.close (); 
}

void Sip::__reconnect__ ( void )
{
    __end_sock__(); 
    sock.init();
    sock.bind( this->my_port );
}
//*[ end ] -------------------------------------- Funcoes de uso interno ---------------------------------------------- *//

  
Sip::Sip ( const int new_ext, const uint16_t my_port )
{
    char inner_tmp [ 20 ];
    
    if ( debug_sip ) debug_msg ("[%d, %d] Building SIP", new_ext, my_port );
    
    this->my_ext = new_ext;
    this->my_port = my_port;
        
    FILE * fip = fopen ( "/qspi/serverip.txt", "r");
    if ( fip == NULL)
    {
        if ( debug_sip ) debug_msg("[%d] Failed to open /qspi/serverip.txt", this->my_ext );
        strncpy ( this->server_ip, SERVER_IP, 20 );    
    } else {
        char tmp [ 16 ] = "\0";
        int read = fread ( tmp, 1, 15, fip );
        if ( read > 0 ){
            for ( int i = 0; i < read; i++ ) 
                if ( tmp [ i ] == '\n' || tmp[ i ] == '\r' ){
                     tmp [ i ] = '\0';
                    break;
                }
            strcpy ( this->server_ip, tmp );
            if ( debug_sip ) debug_msg ("[%d] ip server%s( read %d chars ), valid %d", this->my_ext, this->server_ip, read, strlen( this->server_ip )  );
        }else{
            if ( debug_sip ) debug_msg ("[%d] Failed to read /qspi/serverip.txt", this->my_ext );
            strncpy ( this->server_ip, SERVER_IP, 20 );
        }
    }
    if ( fip ) fclose ( fip );
    this->server_ip [ 15 ] = '\0';
    
    FILE * sp = fopen ( "/qspi/serverport.txt", "r");
    if ( sp == NULL )
    {
        if ( debug_sip ) debug_msg ("[%d] Failed to open /qspi/serverport.txt", this->my_ext );
        this->server_port = SERVER_PORT;
    } else {
        if ( fread ( (void *)inner_tmp, 1, 20, sp ) > 0 )
        {
            server_port = atoi ( inner_tmp );
            if ( debug_sip ) debug_msg ("[%d] server port %d", this->my_ext, this->server_port );
        } else {
            if ( debug_sip ) debug_msg ("F[%d] failed to read /qspi/serverport.txt", this->my_ext );
            this->server_port = SERVER_PORT;
        }
    }
    if ( sp ) fclose ( sp );
    
    FILE * fhip = fopen ( "/qspi/myip.txt", "r");
    if ( fhip == NULL )
    {
        if ( debug_sip ) debug_msg ("[%d] Failed to open /qspi/myip.txt", this->my_ext );
        strncpy ( this->my_ip, MY_IP, 20 );    
    } else {
        char tmp[ 16 ] = "\0";
        int read = fread( tmp, 1, 15, fhip );
        if( read > 0 ){
            for( int i = 0; i < read; i++ ) 
                if( tmp[ i ] == '\n' || tmp[ i ] == '\r' ){
                    tmp[ i ] = '\0';
                    break;
                }
            strcpy ( this->my_ip, tmp );
            if ( debug_sip ) debug_msg ("[%d] ip %s( lidos %d chars ), valid %d", this->my_ext, this->my_ip, read, strlen( this->my_ip ) );
        }else{
            if ( debug_sip ) debug_msg ("[%d] Failed to read /qspi/myip.txt", this->my_ext );
            strncpy ( this->my_ip, MY_IP, 20 );
        }
    }
    if ( fhip ) fclose ( fhip );
    
    this->my_ip[ 15 ] = '\0';
    
    if ( debug_sip ) debug_msg ("[%d] port %d", this->my_ext, this->my_port );
    
    snprintf ( this->my_display, sizeof ( this->my_display ), "%i", this->my_ext );
    
    this->my_rtp_port = 0;
    if ( debug_rtp ) debug_msg ("[%d] rtp port %d ", this->my_ext, this->my_rtp_port );

    FILE * serext = fopen ( "/qspi/peerext.txt", "r");
    if ( serext == NULL )
    {
        if( debug_sip ) debug_msg ("[%d] Failed to open /qspi/peerext.txt", this->my_ext );
        this->peer_ext = PEER_EXT;
    } else {
        if( fread ( (void *)inner_tmp, 1, 32, serext ) > 0 ) {
            this->peer_ext = atoi ( inner_tmp );
            if ( debug_sip ) debug_msg("[%d] server ext %d", this->my_ext, this->peer_ext );
        } else {
            if ( debug_sip ) debug_msg ("Failed to read /qspi/peerext.txt" );
            this->peer_ext = PEER_EXT;
        }
    }
    if ( serext ) fclose ( serext );
    
    strcpy( this->last_invite_tag, "" );
    strcpy( this->last_invite_callid, "");
    strcpy( this->last_branch, "" );
    strcpy( this->SVNREV, "COLA" );
    
    status = sip_idle;
    
    __init_sock__ ();
    
    call = NULL;
    
    waiting = false;
    
    listen_SIP_server_return = 0;
    
    last_cseq = 0;
    
    sip_new_counter++;
}

Sip::~Sip ( void ) 
{
    __end_sock__ ();
    sip_delete_counter++;
}
 
int Sip::registry ( void )
{   
    build_registry_package ();
    
    int send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) ); // > 400
    if ( send != strlen ( buffer ) )
    {
        if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- Registry -- Sent %i of %i bytes", this->my_ext, send, strlen ( buffer ) );
        __reconnect__ ();
        miss_sip_registry_send_pkg++;
    }

    if ( debug_sip ) debug_msg ("[%d %d] Registry -- Sent %i of %i bytes", this->my_ext, this->my_port, send, strlen ( buffer ) );
    
    return ( send ); 
}

VZ_call * Sip::invite ( void )
{
    if ( status == sip_on_call ) return call;
    
    else if ( status == sip_idle )
    {
        int cseq = 0;

        call = NULL;

        build_invite_package( &cseq );
        
        if ( debug_invite ) debug_msg ("cseq::%d", cseq );
        
        if ( drop_invite_to_ast_pkg )
        {
                debug_msg("[%d] Droped invite pkg to ast", this->my_ext );
        }
            else
        {
            int send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) );
            
            if ( send != strlen ( buffer ) )
            {
                if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- Invite", this->my_ext );
                __reconnect__ ();
                miss_sip_invite_send_pkg++;
            }
         
            if ( debug_invite || debug_reconnect ) debug_msg ("[%d] Return value for invite pkg %d", this->my_ext, send );
        }
        
        invite_timer.stop ();
        invite_timer.reset ();
        invite_timer.start ();
        
        sip_set_status ( sip_waiting_trying );
        
        waiting = false;
    }
    
    if ( invite_timer.read() > INVITE_MAX_WAITING_TIME )
    {
        if ( debug_invite ) debug_msg ("[%d] Invite call timeout :(", this->my_ext );
        invite_timer.stop ();
        invite_timer.reset ();
        sip_set_status ( sip_denied );
        send_bye ();
        
        call = NULL;
        return ( NULL );
    }
    
    if ( waiting == true ) { return call; }
    
    else return ( NULL );
}
 
char * Sip::build_registry_package ( void )
{
    char branch[ SIP_MAXFIELDSIZE ];
    char tag[ SIP_MAXFIELDSIZE ];
    char callid[ SIP_MAXFIELDSIZE ];
    fill_random16h( branch );
    fill_random( tag, 18 );
    fill_random16h( callid );
    
    snprintf( buffer, sizeof( buffer ) - 1, 
        "REGISTER sip:%s:%d SIP/2.0\r\nVia: SIP/2.0/UDP %s:%d;branch=%s\r\n"
        "From: %d <sip:%d@%s:%d>;tag=%s\r\n"
        "To: %d <sip:%d@%s:%d>\r\n"
        "Call-ID: %s\r\n"
        "CSeq: %d REGISTER\r\n"
        "Max-Forwards: 70\r\n"
        "Contact: %d <sip:%d@%s:%d>;expires=270\r\n"
        "User-Agent: VZtech/pabxdriver-%s\r\n"
        "Content-Length: 0\r\n"
        "%s\r\n\r\n",
        server_ip, server_port, my_ip, my_port, branch,
        my_ext, my_ext, server_ip, server_port, tag,
        my_ext, my_ext, server_ip, server_port, 
        callid, 
        get_cseq(), 
        my_ext, my_ext, my_ip, server_port, 
        SVNREV,
        SIP_ALLOW
    );
    return ( buffer );
}

char * Sip::build_invite_package ( int * cseq, const bool retry )
{
    char header [ SIP_MAXMSGSIZE ];
    char body [ SIP_MAXMSGSIZE ];
    char branch [ SIP_MAXFIELDSIZE ];
    char tag [ SIP_MAXFIELDSIZE ];
    char callid [ SIP_MAXFIELDSIZE ];
    char callbox_string[ CALLBOX_STRING_SIZE ];
    
    int snprintf_ret = snprintf ( callbox_string, CALLBOX_STRING_SIZE - 1, "%i", this->my_ext );
    
    if ( snprintf_ret == CALLBOX_STRING_SIZE ) callbox_string [ CALLBOX_STRING_SIZE - 1 ] = '\0';
    
    if ( !retry )
    {
        *cseq = get_cseq();
        last_cseq = *cseq;
        
        fill_random16h ( branch );
        strcpy ( last_branch, branch );
        
        fill_random ( tag, 18 );
        strcpy ( last_invite_tag, tag );
        
        fill_random16h ( callid );
        strcpy ( last_invite_callid, callid );
        
        this->my_rtp_port = fill_random_rtp_port ();
    }
        else
    {
        *cseq = last_cseq;
        
        strcpy ( branch, last_branch  );
        
        strcpy ( tag, last_invite_tag );
        
        strcpy ( callid, last_invite_callid );
    }
    
    if ( debug_invite ) debug_msg ("[%d] \r\nbranch :: %s\r\ntag :: %s\r\ncallid :: %s", this->my_ext, branch, tag, callid );
    
    if ( debug_rtp || debug_invite ) debug_msg ("[%d] Invite PKG rtp port ( %d )", this->my_ext, this->my_rtp_port );

    snprintf( header, SIP_MAXMSGSIZE,
        "INVITE sip:%i@%s:%i SIP/2.0\r\n"
        "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
        "From: %s <sip:%i@%s:%i>;tag=%s\r\n"
        "To: <sip:%i@%s:%i>\r\n"
        "Call-ID: %s@%s\r\n"
        "CSeq: %i INVITE\r\n"
        "Contact: %i <sip:%i@%s:%i>\r\n"
        "Max-Forwards: 20\r\n"
        "User-Agent: VZtech/pabxdriver-%s\r\n"
        "Expires: 71\r\n"
        "%s\r\n"
        "Content-Type: application/sdp\r\n",
        this->peer_ext, this->server_ip, this->server_port, 
        this->my_ip, this->my_port, branch, 
        callbox_string, this->my_ext, this->server_ip, this->server_port, tag,
        this->peer_ext, this->server_ip, this->server_port, 
        callid, this->my_ip, 
        *cseq,
        this->my_ext, this->my_ext, this->my_ip, this->my_port, 
        SVNREV, 
        SIP_ALLOW
    );
    
    snprintf( body, SIP_MAXMSGSIZE,
        "v=0\r\no=- 7377 18176 IN IP4 %s\r\n"
        "s=-\r\n"
        "c=IN IP4 %s\r\n"
        "t=0 0\r\n"
        "i=UDP %i\r\n"
        "m=audio %i RTP/AVP 8 101\r\n"
        "a=rtpmap:8 PCMA/8000/1\r\n"
        "a=rtpmap:101 telephone-event/8000\r\n"
        "a=fmtp: 101 0-11",
        this->my_ip,
        this->my_ip,
        this->my_rtp_port,
        this->my_rtp_port
    );
    
    strcpy( this->buffer, header );
    
    char content_Length_msg [ CONTENT_LENGTH_MSG_SIZE ];
    
    snprintf_ret = snprintf ( content_Length_msg, CONTENT_LENGTH_MSG_SIZE, "Content-Length: %d\r\n\r\n", strlen ( body ) );
    if ( snprintf_ret == CONTENT_LENGTH_MSG_SIZE ) content_Length_msg [ CONTENT_LENGTH_MSG_SIZE - 1 ] = '\0';
    strcat( this->buffer, content_Length_msg );
    
    strcat( this->buffer, body );
    
    if ( debug_invite ) debug_msg ("[%d] strlen( header [%d] ) | strlen( body [%d] ) | ( h + b [%d])", this->my_ext, strlen( header ),strlen( body ), strlen( header ) + strlen( body ) );
    
    return( this->buffer );
}
 
char * Sip::build_bye_package ( void )
{
    char branch[SIP_MAXFIELDSIZE];
    char tag[SIP_MAXFIELDSIZE];
    fill_random16h(branch);
    fill_random(tag,18);
    
    snprintf(
        this->buffer, sizeof ( this->buffer ) - 1,
        "BYE sip:%i@%s:%i SIP/2.0\r\n"
        "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
        "From: %i <sip:%i@%s:%i>;tag=%s\r\n"
        "To: <sip:%i@%s:%i>;tag=%s\r\n"    
        "Call-ID: %s@%s\r\n"
        "CSeq: %i BYE\r\n"
        "Max-Forwards: 70\r\n"
        "User-Agent: VZtech/pabxdriver-%s\r\n"
        "Content-Length: 0\r\n\r\n",        
        this->peer_ext, this->server_ip, this->server_port, 
        this->my_ip, this->my_port, branch, 
        this->my_ext, this->my_ext, this->server_ip, this->server_port, last_invite_tag, 
        this->peer_ext, this->server_ip, this->server_port, tag, 
        last_invite_callid, this->my_ip,
        get_cseq(),
        SVNREV
    );
    
    return( buffer );
}
char * Sip::build_ack_package ( char * buffer, const unsigned char * orig )
{
    char to[ SIP_MAXFIELDSIZE ];
    char from[ SIP_MAXFIELDSIZE ];
    char callid[ SIP_MAXFIELDSIZE ];
    char via[ SIP_MAXFIELDSIZE ];
    char branch[ SIP_MAXFIELDSIZE ];
    char cseq[ SIP_MAXFIELDSIZE ];
    
    if( decode_gettag( orig, "to: ", to ) == 0) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "from: ", from ) == 0) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "call-id: ", callid ) == 0) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    decode_branch( orig, branch );
    decode_cseq( orig, cseq );
    
    if( strlen( via ) > 6 ) {
        if( strcasecmp( ";rport", via+strlen( via )-6) == 0) {
            via[strlen(via)-6] = 0;
        }
    }
    
    
    snprintf ( buffer, SIP_MAXMSGSIZE -1,
        "ACK sip:%i@%s:%i SIP/2.0\r\n"
        "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
        "From: %s\r\n"
        "To: %s\r\n"
        "Call-ID: %s\r\n"
        "CSeq: %s ACK\r\n"
        "Max-Forwards: 70\r\n"
        "Contact: %i <sip:%i@%s:%i>\r\n"
        "User-Agent: VZtech/pabxdriver-%s\r\n"
        "Content-Length: 0\r\n\r\n",         
        this->peer_ext, this->server_ip, this->server_port, 
        this->my_ip, this->my_port, branch,
        from, 
        to, 
        callid, 
        cseq, 
        this->my_ext, this->my_ext, this->my_ip, this->my_port,
        SVNREV 
    );
    
    return( buffer );
}

char * Sip::build_reply_package ( char * buffer, const unsigned char * orig )
{
    char to[ SIP_MAXFIELDSIZE ];
    char from[ SIP_MAXFIELDSIZE ];
    char callid[ SIP_MAXFIELDSIZE ];
    char cseq[ SIP_MAXFIELDSIZE ];
    char via[ SIP_MAXFIELDSIZE ];
    char tag[ SIP_MAXFIELDSIZE ];
 
    if( decode_gettag( orig, "to: ", to ) == 0) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "from: ", from ) == 0) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "call-id: ", callid ) == 0 ) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "cseq: ", cseq) == 0 ) {
        buffer[ 0 ] = 0;
        return NULL;
    }
    if( decode_gettag( orig, "via: ", via) == 0 ) {
        buffer[ 0 ] = 0;
        return NULL;
    }
 
    if (strlen(via) > 6) {
        if (strcasecmp(";rport",via+strlen(via)-6)==0) {
            via[strlen(via)-6] = 0;
        }
    }
    
    fill_random ( tag, 18 );
    
    snprintf(
        buffer, SIP_MAXMSGSIZE -1,
        "SIP/2.0 200 OK\r\n"    
        "To: %s;tag=%s\r\n"
        "From: %s\r\n"
        "Call-ID: %s\r\n"
        "CSeq: %s\r\n"
        "Via: %s\r\n"
        "Server: VZtech/pabxdriver-%s\r\n"
        "Content-Length: 0\r\n"
        "%s\r\n\r\n",
        to, tag, 
        from, 
        callid,
        cseq,
        via,
        SVNREV,
        SIP_ALLOW
    );
    
    return( buffer );
}

char * Sip::fill_random16h ( char * buffer )
{
    fill_random( buffer, 16 );
    buffer[ 7 ] = '-';
    return( buffer );
}
 
char * Sip::fill_random ( char * buffer, const int size )
{
    static uint16_t seed = time( NULL );
    seed += 1;
    srand( seed );
 
    for( int i = 0; i < size - 1; i++ )
    {
        buffer[ i ] = fill_random_aux[ rand() & 0x3f ];
    }
    
    buffer[ size - 1 ] = 0;
    return( buffer );
}
 
int Sip::get_cseq ( void )
{
    static unsigned int cseq = 0;
    if( cseq == 0 )
    {
        /* initial value, random number */
        cseq = rand ();
        cseq &= 0x7fff;
    }
    cseq++;
    cseq &= 0x7fff;
    if ( cseq == 0 ) cseq++;
    return cseq;
}
 
char * Sip::decode_cseq ( const unsigned char * package, char * cseq )
{
    char pkg[ SIP_MAXMSGSIZE ], cs[ SIP_MAXMSGSIZE ];
    
    if( decode_gettag ( package, "cseq: ", pkg ) != 0)
    {
        int i = 0;
        strcpy ( cs, pkg );
        while ( ( cs [ i ] != 0 ) && ( cs [ i ] != ' ' ) ) i++;
        cs [ i ] = 0;
        strcpy ( cseq, cs );
    } else {
        cseq [ 0 ] = 0;
    }
    return ( cseq );
}
 
char * Sip::decode_branch ( const unsigned char * package, char * branch )
{
    char pkg[ SIP_MAXMSGSIZE ];
    
    if ( decode_gettag ( package, "branch=", pkg ) != 0 )
    {
        int i = 0;
        strcpy ( branch, pkg );
        while ( ( branch [ i ] != 0 ) && ( branch [ i ] != ';' ) ) i++;
        branch [ i ] = 0;
    } else {
        branch [ 0 ] = 0;
    }
    
    return ( branch );
}

int Sip::decode_gettag ( const unsigned char * package, const char * tag, char * out )
{
    int cmpsize = strlen ( tag );
    int size = strlen ( ( char * ) package ) - cmpsize;
    
    for ( int i = 0; i < size; i++ )
    {
        if ( strncasecmp( tag, ( char * ) package + i, cmpsize ) == 0 )
        {
            char * s;
            s = ( char * ) package + i + cmpsize;
            register int j = 0;
            while ( ( s [ j ] != '\r' ) && ( s [ j ] != '\n' ) ) j++;
            strncpy ( out, s, j ); // copy string to output
            out [ j ] = 0; // terminate string
            return 1; // found
        }
    }
    
    return 0; // not found
}

int Sip::get_my_rtp_port ( void ) { return this->my_rtp_port; }

int Sip::fill_random_rtp_port ( void )
{
    static uint16_t port = 0;
    port += 2;
    port &= 0x7fe; // 0 to 2046, always even
    return port + 16384;
}

void Sip::set_server_port ( const int new_server_port ) { this->server_port = new_server_port; }

void Sip::set_server_ext ( const int new_server_ext ) { this->peer_ext = new_server_ext; }

void Sip::set_server_ip ( const char * new_server_ip )
{
    strncpy( this->server_ip, new_server_ip, 20 );
    this->server_ip[19] = 0;
}

/*  Retorna 
    = 0 :: ok
    < 0 :: tive problemas
    > 0 :: devo remover essa call do vetor de calls 
*/
int Sip::listen_SIP_server ( void )
{
    int ret = listen_SIP_server_return;
    listen_SIP_server_return = 0;
    return ret;
}

void Sip::set_ext ( const int ext ) { my_ext = ext; }

void Sip::set_port ( const int port ) { my_port = port; }

void Sip::send_bye ( void )
{
    int send = sock.sendTo( sip_server, build_bye_package (), strlen( this->buffer ) );
    
    if( debug_sip ) debug_msg( "[%d] sizeof( bye pkg ) :: %d", this->my_ext, strlen( this->buffer ) );
    
    if( send != strlen( this->buffer ) )
    {
        if( debug_reconnect ) debug_msg("[%d] Reconnect SIP -- BYE, %d, %d", this->my_ext, send, strlen( this->buffer ) );
        __reconnect__();
        miss_sip_bye_send_pkg++;
    }
}

int Sip::get_status ( void ) { return this->status; }

void Sip::sip_set_status ( const uint8_t status ) { this->status = status; }

int Sip::get_socket_fd ( void ) { return sock.get_fd (); }

int Sip::udp_incomming_pkg ( void )
{
    Endpoint from;  
    
    int length = sock.receiveFrom ( from, buffer, sizeof( buffer ) );
    
    if ( memcmp( ( ( u8_t * )( &(from._remoteHost) ) ) + 2, ( ( u8_t * )( &(sip_server._remoteHost) ) ) + 2, 6 ) != 0 ) return 0;
    
    if ( length == -1 )
    {
        if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- UDP Incomming", get_ext () );
        __reconnect__();
        miss_sip_inc_pkg++;
    }
    
    if ( length > 0 )
    {
        if ( sizeof( buffer ) > length ) buffer[ length ] = 0;
        
        int sip_response = -1;
        
        // faster than atoi() (: 
        if ( buffer[ 7 ] == ' ' || buffer[ 11 ] == ' ' ){
            sip_response = ( buffer[ 8 ] - '0' ) * 100 + ( buffer[ 9 ] - '0' ) * 10 + ( buffer[ 10 ] - '0' );
        }
        
        if ( ( status == sip_trying ) || ( status == sip_ringing ) || ( status == sip_waiting_trying ) || ( status == sip_on_call ) )
        { 
            if ( sip_response == 200 ){ // Ok    
                char *ref = strstr( buffer, "audio" );
                if ( debug_invite ) debug_msg("[%d] udp_incomming_pkg -- ok", this->my_ext );
                if ( ref != NULL ){
                    if ( drop_this_amount_of_ack_to_ast ) drop_this_amount_of_ack_to_ast--;
                        
                    if ( drop_this_amount_of_ack_to_ast )
                    {
                        debug_msg ("[%d] Droped ok pkg received from ast (%d)", this->my_ext, drop_this_amount_of_ack_to_ast );
                        return -71;    
                    }
                                        
                    ref += 6; // audio 
                    ref = strtok( ref, " ");
                    if ( call == NULL ){
                        call = new VZ_call ( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
                        if ( debug_rtp ) debug_msg ("[%d] Ok new call ( %d, %d, %d, %d ( %s ) ) ", this->my_ext, this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ), ref );
                        if ( call == NULL ) memory_is_over = true;
                    }
                    char ans[ SIP_MAXMSGSIZE ];
                    build_ack_package( ans, ( unsigned char *)buffer );
                    
                    int send = 0;
                    
                    if ( drop_ack_pkg )
                    {
                        debug_msg("[%d] Droped ack pkt to ast", this->my_ext );
                    }
                        else
                    {
                        send = sock.sendTo( sip_server, ans, strlen( ans ) );
                    
                        if ( send != strlen( ans ) )
                        {
                            if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- Ok -- Call mode on", this->my_ext );
                            __reconnect__();
                            miss_sip_ok_send_pkg++;
                        }
                    }
                    
                    if ( debug_invite ) debug_msg ("[%d] Call alocada -- sizeof( ack ) :: %d - strlen( ans ):: %d", this->my_ext, send, strlen( ans ) );
                    sip_set_status ( sip_on_call );
                }
            }
        }
        if ( ( status == sip_trying ) || ( status == sip_ringing ) )
        {
            if ( sip_response >= 400 && sip_response < 700 )
            {
                if ( debug_invite ) { 
                    buffer[ 11 ] = 0; 
                    if ( debug_invite ) debug_msg ("[%d] Busy Here :: %s", this->my_ext, buffer + 8 );
                }
                send_bye();
                sip_set_status ( sip_busy );
                return ( NULL );  
            }
                else if ( sip_response == 183 ) // Session in Progress
            {
                char *ref = strstr ( buffer, "audio" );
                if ( ref != NULL )
                {
                    ref += 6; // strlen( "audio" ) == 6
                    ref = strtok( ref, " ");
                    if ( call == NULL )
                    {
                        this->call = new VZ_call ( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
                        if ( debug_rtp ) debug_msg ("[%d] Session in Progress ( %d, %d, %d, %d ( %s ) ) ",this->my_ext, this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ), ref );
                        if ( call == NULL ) memory_is_over = true;
                    }
                    waiting = true;
                }
            }
        }
        
        if ( status == sip_trying ){
            if ( sip_response == 180 ){
                if ( debug_invite ) debug_msg ("[%d] ringing", this->my_ext );
                sip_set_status ( sip_ringing );
            }
        }
        
        if ( status == sip_waiting_trying ){
            if ( sip_response == 100 ){
                if ( debug_invite ) debug_msg ("[%d] trying", this->my_ext )
                sip_set_status ( sip_trying );
            }
        }
        
        if ( status == sip_on_call )
        {
            if ( !( strncasecmp( buffer, "bye ", 4 ) ) )
            {
                char ans[ 2000 ];
                build_reply_package ( ans, ( unsigned char * ) buffer );
                
                int send = sock.sendTo ( sip_server, ans, strlen ( ans ) );
                if ( send != strlen( ans ) )
                {
                    if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- RCV BYE from * -- ( expected, realized ) ( %d, %d )", this->my_ext, strlen ( ans ), send );
                    __reconnect__ ();
                    miss_sip_rcv_bye_send_pkg++;
                }
                
                if ( debug_invite ) debug_msg ("[%d] Bye request received from * - sizeof( bye reply pkg ) :: %d", this->my_ext, strlen ( ans ) );
                
                
                set_sip_rtp_port ( 0 );
                
                listen_SIP_server_return = my_ext;
            }
        }
    }
    
    return length;
}

void Sip::reset_call ( void ) { if( call != NULL ) call = NULL; }

int Sip::get_ext ( void ) { return my_ext; }

int Sip::get_port ( void ) { return my_port; }

int Sip::get_sip_rtp_port ( void ) { return my_rtp_port; }

void Sip::set_sip_rtp_port ( const int new_my_rtp_port )
{ 
    this->my_rtp_port = new_my_rtp_port; 
    if ( debug_rtp ) debug_msg ( "[%d] this->my_rtp_port ( %d ) = new_my_rtp_port( %d )", this->my_ext, this->my_rtp_port, new_my_rtp_port );
}

int Sip::print_yourself ( void )
{
    send_msg ("");
    send_msg ("Values ::\r\n");
    send_msg ("server_ip :: %s", server_ip );
    send_msg ("server_port :: %d", server_port );
    send_msg ("my_ip :: %s", my_ip );
    send_msg ("my_port :: %d", my_port );
    send_msg ("my_ext :: %d", my_ext );
    send_msg ("my_rtp_port :: %d", my_rtp_port );
    send_msg ("my_display :: %s", my_display );
    send_msg ("peer_ext :: %d", peer_ext );
    send_msg ("fill_random_aux :: %s", fill_random_aux );
    send_msg ("last_invite_tag :: %s", last_invite_tag );
    send_msg ("last_invite_callid :: %s", last_invite_callid );
    send_msg ("SVNREV :: %s", SVNREV );
    send_msg ("char buffer[ 1024 ] :: %p", ( void * ) buffer );
    
    //FIXME esse tipo de tag existe como metalinguagem ???
    //TOTHINK o que fazer pra entender melhor o estado dos sockets
    send_msg ("UDPSocket sock :: %p", ( void * ) &sock );
    send_msg ("Endpoint sip_server :: %p", ( void * ) &sip_server );
    
    send_msg ("call :: %p", ( void * ) call );
    send_msg ("invite_timer :: %d", ( int ) invite_timer.read () );
    send_msg ("waiting ::  %s", ( waiting ) ? "true" : "false" );
    send_msg ("listen_SIP_server_return :: %d", listen_SIP_server_return );
    send_msg ("");

    return ( sizeof( Sip ) );    
}

int Sip::retry_send_last_invite_pkg_to_ast ( void )
{
    char callbox_string [ 32 ];
    snprintf ( callbox_string, sizeof ( callbox_string ) -1, "%i", my_ext );
    
    int cseq = 0;

    call = NULL;

    build_invite_package ( &cseq, true );
    
    if ( debug_invite ) debug_msg ("cseq::%d", cseq );
    
    int send = 0;
    
    if ( drop_invite_to_ast_pkg )
    {
            debug_msg ("[%d] Droped invite pkg to ast", this->my_ext );
    }
        else
    {
        
        send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) );
        
        if ( send != strlen( buffer ) )
        {
            if ( debug_reconnect ) debug_msg ("[%d] Reconnect SIP -- Invite", this->my_ext );
            __reconnect__ ();
            miss_sip_invite_send_pkg++;
        }
     
        if ( debug_invite || debug_reconnect ) debug_msg ("[%d] Return value for invite pkg %d", this->my_ext, send );
    }
    
    return ( send );
}