VZTECH / Mbed 2 deprecated main_src

Dependencies:   EALib EthernetInterface_vz mbed-rtos mbed

Fork of header_main_colinas_V0-20-09-14 by VZTECH

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sip.cpp Source File

sip.cpp

00001 #include "sip.h"
00002 
00003 //*[ begin ] ------------------------------------ Funcoes de uso interno ---------------------------------------------- *//
00004 void Sip::__init_sock__ ( void )
00005 {
00006     sip_server.set_address ( this->server_ip , this -> server_port );
00007     sock.bind ( this -> my_port );
00008     sock.set_blocking ( false, 0 );
00009 }
00010 
00011 void Sip::__end_sock__ ( void )
00012 {
00013     sock.close (); 
00014 }
00015 
00016 void Sip::__reconnect__ ( void )
00017 {
00018     __end_sock__ (); 
00019     __init_sock__ ();
00020 }
00021 //*[ end ] -------------------------------------- Funcoes de uso interno ---------------------------------------------- *//
00022 
00023   
00024 Sip::Sip ( const int new_ext, const uint16_t my_port )
00025 {
00026     if ( debug_sip ) vz_debug ("[%d, %d] Building SIP", new_ext, my_port );
00027     
00028     this->my_ext = new_ext;
00029     this->my_port = my_port;
00030       
00031     cm -> get_server_ip ( this->server_ip );
00032     this->server_port = cm -> get_server_port ();
00033     cm -> get_header_ip ( this->my_ip );
00034     
00035     if ( debug_sip ) vz_debug ("[%d] port %d", this->my_ext, this->my_port );
00036     
00037     snprintf ( this -> my_display, sizeof ( this -> my_display ), "%i", this -> my_ext );
00038     
00039     this->my_rtp_port = 0;
00040     if ( debug_rtp ) vz_debug ("[%d] rtp port %d ", this->my_ext, this->my_rtp_port );
00041 
00042 
00043     this->peer_ext = cm -> get_server_ext ();
00044     
00045     strcpy( this->last_invite_tag, "" );
00046     strcpy( this->last_invite_callid, "");
00047     strcpy( this->last_branch, "" );
00048     strcpy( this->SVNREV, "COLA" );
00049     
00050     status = sip_idle;
00051     
00052     __init_sock__ ();
00053     
00054     call = NULL;
00055     
00056     waiting = false;
00057     
00058     listen_SIP_server_return = 0;
00059     
00060     last_cseq = 0;
00061     
00062     sip_new_counter++;
00063 }
00064 
00065 Sip::~Sip ( void ) 
00066 {
00067     __end_sock__ ();
00068     sip_delete_counter++;
00069 }
00070  
00071 int Sip::registry ( void )
00072 {   
00073     build_registry_package ();
00074     
00075     int send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) ); // > 400
00076     if ( send not_eq strlen ( buffer ) )
00077     {
00078         if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- Registry -- Sent %i of %i bytes", this->my_ext, send, strlen ( buffer ) );
00079         __reconnect__ ();
00080         miss_sip_registry_send_pkg ++;
00081     }
00082 
00083     if ( debug_sip ) vz_debug ("[%d %d] Registry -- Sent %i of %i bytes", 
00084                     this -> my_ext, this -> my_port, send, strlen ( buffer ) );
00085     
00086     return ( send ); 
00087 }
00088 
00089 VZ_call * Sip::invite ( void )
00090 {
00091     if ( status == sip_on_call ) return call;
00092     
00093     else if ( status == sip_idle )
00094     {
00095         int cseq = 0;
00096 
00097         call = NULL;
00098 
00099         build_invite_package( &cseq );
00100         
00101         if ( debug_invite ) vz_debug ("cseq::%d", cseq );
00102         
00103         if ( drop_invite_to_ast_pkg )
00104         {
00105                 vz_debug ("[%d] Droped invite pkg to ast", this->my_ext );
00106         }
00107             else
00108         {
00109             int send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) );
00110             
00111             if ( send not_eq strlen ( buffer ) )
00112             {
00113                 if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- Invite", this->my_ext );
00114                 __reconnect__ ();
00115                 miss_sip_invite_send_pkg++;
00116             }
00117          
00118             if ( debug_invite || debug_reconnect ) vz_debug ("[%d] Return value for invite pkg %d", this->my_ext, send );
00119         }
00120         
00121         invite_timer.stop ();
00122         invite_timer.reset ();
00123         invite_timer.start ();
00124         
00125         sip_set_status ( sip_waiting_trying );
00126         
00127         waiting = false;
00128     }
00129     
00130     if ( invite_timer.read () > INVITE_MAX_WAITING_TIME )
00131     {
00132         if ( debug_invite ) vz_debug ("[%d] Invite call timeout :(", this -> my_ext );
00133         invite_timer.stop ();
00134         invite_timer.reset ();
00135         sip_set_status ( sip_denied );
00136         send_bye ();
00137         
00138         call = NULL;
00139         return ( NULL );
00140     }
00141     
00142     if ( waiting == true ) { return call; }
00143     
00144     else return ( NULL );
00145 }
00146  
00147 char * Sip::build_registry_package ( void )
00148 {
00149     char branch [ SIP_MAXMSGSIZE ];
00150     char tag [ SIP_MAXMSGSIZE ];
00151     char callid [ SIP_MAXMSGSIZE ];
00152     fill_random16h ( branch );
00153     fill_random ( tag, 18 );
00154     fill_random16h ( callid );
00155     
00156     snprintf( buffer, sizeof( buffer ) - 1, 
00157         "REGISTER sip:%s:%d SIP/2.0\r\nVia: SIP/2.0/UDP %s:%d;branch=%s\r\n"
00158         "From: %d <sip:%d@%s:%d>;tag=%s\r\n"
00159         "To: %d <sip:%d@%s:%d>\r\n"
00160         "Call-ID: %s\r\n"
00161         "CSeq: %d REGISTER\r\n"
00162         "Max-Forwards: 70\r\n"
00163         "Contact: %d <sip:%d@%s:%d>;expires=270\r\n"
00164         "User-Agent: VZtech/pabxdriver-%s\r\n"
00165         "Content-Length: 0\r\n"
00166         "%s\r\n\r\n",        
00167         server_ip, server_port, my_ip, my_port, branch,
00168         my_ext, my_ext, server_ip, server_port, tag,
00169         my_ext, my_ext, server_ip, server_port, 
00170         callid, 
00171         get_cseq(), 
00172         my_ext, my_ext, my_ip, my_port,
00173         SVNREV,
00174         SIP_ALLOW
00175     );
00176     return ( buffer );
00177 }
00178 
00179 char * Sip::build_invite_package ( int * cseq, const bool retry )
00180 {
00181     char header [ SIP_MAXMSGSIZE ];
00182     char body [ SIP_MAXMSGSIZE ];
00183     char branch [ SIP_MAXMSGSIZE ];
00184     char tag [ SIP_MAXMSGSIZE ];
00185     char callid [ SIP_MAXMSGSIZE ];
00186     char callbox_string[ CALLBOX_STRING_SIZE ];
00187     
00188     int snprintf_ret = snprintf ( callbox_string, CALLBOX_STRING_SIZE - 1, "%i", this->my_ext );
00189     
00190     if ( snprintf_ret == CALLBOX_STRING_SIZE ) callbox_string [ CALLBOX_STRING_SIZE - 1 ] = '\0';
00191     
00192     if ( !retry )
00193     {
00194         *cseq = get_cseq ();
00195         last_cseq = *cseq;
00196         
00197         fill_random16h ( branch );
00198         strcpy ( last_branch, branch );
00199         
00200         fill_random ( tag, 18 );
00201         strcpy ( last_invite_tag, tag );
00202         
00203         fill_random16h ( callid );
00204         strcpy ( last_invite_callid, callid );
00205         
00206         this->my_rtp_port = fill_random_rtp_port ();
00207     }
00208         else
00209     {
00210         *cseq = last_cseq;
00211         
00212         strcpy ( branch, last_branch  );
00213         
00214         strcpy ( tag, last_invite_tag );
00215         
00216         strcpy ( callid, last_invite_callid );
00217     }
00218     
00219     if ( debug_invite ) vz_debug ("[%d] branch :: %s -- tag :: %s -- callid :: %s", this->my_ext, branch, tag, callid );
00220     
00221     if ( debug_rtp || debug_invite ) vz_debug ( "[%d] Invite PKG rtp port ( %d )", this->my_ext, this->my_rtp_port );
00222 
00223     snprintf( header, sizeof ( header ) -1,
00224         "INVITE sip:%i@%s:%i SIP/2.0\r\n"
00225         "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
00226         "From: %s <sip:%i@%s:%i>;tag=%s\r\n"
00227         "To: <sip:%i@%s:%i>\r\n"
00228         "Call-ID: %s@%s\r\n"
00229         "CSeq: %i INVITE\r\n"
00230         "Contact: %i <sip:%i@%s:%i>\r\n"
00231         "Max-Forwards: 20\r\n"
00232         "User-Agent: VZtech/pabxdriver-%s\r\n"
00233         "Expires: 71\r\n"
00234         "%s\r\n"
00235         "Content-Type: application/sdp\r\n",
00236         this->peer_ext, this->server_ip, this->server_port, 
00237         this->my_ip, this->my_port, branch, 
00238         callbox_string, this->my_ext, this->server_ip, this->server_port, tag,
00239         this->peer_ext, this->server_ip, this->server_port, 
00240         callid, this->my_ip, 
00241         *cseq,
00242         this->my_ext, this->my_ext, this->my_ip, this->my_port, 
00243         SVNREV, 
00244         SIP_ALLOW
00245     );
00246     
00247     snprintf( body, sizeof ( body ) - 1,
00248         "v=0\r\no=- 7377 18176 IN IP4 %s\r\n"
00249         "s=-\r\n"
00250         "c=IN IP4 %s\r\n"
00251         "t=0 0\r\n"
00252         "i=UDP %i\r\n"
00253         "m=audio %i RTP/AVP 8 101\r\n"
00254         "a=rtpmap:8 PCMA/8000/1\r\n"
00255         "a=rtpmap:101 telephone-event/8000\r\n"
00256         "a=fmtp: 101 0-11",
00257         this->my_ip,
00258         this->my_ip,
00259         this->my_rtp_port,
00260         this->my_rtp_port
00261     );
00262     
00263     strcpy( this->buffer, header );
00264     
00265     char content_Length_msg [ CONTENT_LENGTH_MSG_SIZE ];
00266     
00267     snprintf_ret = snprintf ( content_Length_msg, CONTENT_LENGTH_MSG_SIZE, "Content-Length: %d\r\n\r\n", strlen ( body ) );
00268     if ( snprintf_ret == CONTENT_LENGTH_MSG_SIZE ) content_Length_msg [ CONTENT_LENGTH_MSG_SIZE - 1 ] = '\0';
00269     strcat( this->buffer, content_Length_msg );
00270     
00271     strcat( this->buffer, body );
00272     
00273     if ( debug_invite ) vz_debug ("[%d] strlen( header [%d] ) | strlen( body [%d] ) | ( h + b [%d])", this->my_ext, strlen( header ),strlen( body ), strlen( header ) + strlen( body ) );
00274     
00275     return( this->buffer );
00276 }
00277  
00278 char * Sip::build_bye_package ( void )
00279 {
00280     char branch [ SIP_MAXMSGSIZE ];
00281     char tag [ SIP_MAXMSGSIZE ];
00282     fill_random16h ( branch );
00283     fill_random (tag,18 );
00284     
00285     snprintf(
00286         this -> buffer, sizeof ( this -> buffer ) - 1,
00287         "BYE sip:%i@%s:%i SIP/2.0\r\n"
00288         "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
00289         "From: %i <sip:%i@%s:%i>;tag=%s\r\n"
00290         "To: <sip:%i@%s:%i>;tag=%s\r\n"    
00291         "Call-ID: %s@%s\r\n"
00292         "CSeq: %i BYE\r\n"
00293         "Max-Forwards: 70\r\n"
00294         "User-Agent: VZtech/pabxdriver-%s\r\n"
00295         "Content-Length: 0\r\n\r\n",        
00296         this->peer_ext, this->server_ip, this->server_port, 
00297         this->my_ip, this->my_port, branch, 
00298         this->my_ext, this->my_ext, this->server_ip, this->server_port, last_invite_tag, 
00299         this->peer_ext, this->server_ip, this->server_port, tag, 
00300         last_invite_callid, this->my_ip,
00301         get_cseq(),
00302         SVNREV
00303     );
00304     
00305     return( buffer );
00306 }
00307 char * Sip::build_ack_package ( void )
00308 {
00309     if ( this -> buffer not_eq NULL )
00310     {   
00311         char to [ SIP_MAXMSGSIZE ];
00312         char from [ SIP_MAXMSGSIZE ];
00313         char callid [ SIP_MAXMSGSIZE ];
00314         char branch [ SIP_MAXMSGSIZE ];
00315         char cseq [ SIP_MAXMSGSIZE ];
00316         
00317         if( decode_gettag( ( const unsigned char * ) this -> buffer, "to: ", to ) == 0) {
00318             buffer[ 0 ] = 0;
00319             return NULL;
00320         }
00321         if( decode_gettag( ( const unsigned char * ) this -> buffer, "from: ", from ) == 0) {
00322             buffer[ 0 ] = 0;
00323             return NULL;
00324         }
00325         if( decode_gettag( ( const unsigned char * ) this -> buffer, "call-id: ", callid ) == 0) {
00326             buffer[ 0 ] = 0;
00327             return NULL;
00328         }
00329         
00330         decode_branch ( ( const unsigned char * ) this -> buffer, branch );
00331         decode_cseq ( ( const unsigned char * ) this -> buffer, cseq );
00332         
00333         snprintf ( buffer, sizeof ( buffer ) - 1,
00334             "ACK sip:%i@%s:%i SIP/2.0\r\n"
00335             "Via: SIP/2.0/UDP %s:%i;branch=%s\r\n"
00336             "From: %s\r\n"
00337             "To: %s\r\n"
00338             "Call-ID: %s\r\n"
00339             "CSeq: %s ACK\r\n"
00340             "Max-Forwards: 70\r\n"
00341             "Contact: %i <sip:%i@%s:%i>\r\n"
00342             "User-Agent: VZtech/pabxdriver-%s\r\n"
00343             "Content-Length: 0\r\n\r\n",         
00344             this -> peer_ext, this -> server_ip, this -> server_port, 
00345             this -> my_ip, this -> my_port, branch,
00346             from, 
00347             to, 
00348             callid, 
00349             cseq, 
00350             this -> my_ext, this -> my_ext, this -> my_ip, this -> my_port,
00351             SVNREV 
00352         );
00353         
00354         return( buffer );
00355     }
00356         else
00357     {
00358         return ( NULL );    
00359     }
00360 }
00361 
00362 char * Sip::build_reply_package ( void )
00363 {
00364     char to [ SIP_MAXMSGSIZE ];
00365     char from [ SIP_MAXMSGSIZE ];
00366     char callid [ SIP_MAXMSGSIZE ];
00367     char cseq [ SIP_MAXMSGSIZE ];
00368     char via [ SIP_MAXMSGSIZE ];
00369     char tag [ SIP_MAXMSGSIZE ];
00370  
00371     if( decode_gettag( ( const unsigned char * ) buffer, "to: ", to ) == 0) {
00372         buffer[ 0 ] = 0;
00373         return NULL;
00374     }
00375     if( decode_gettag( ( const unsigned char * ) buffer, "from: ", from ) == 0) {
00376         buffer[ 0 ] = 0;
00377         return NULL;
00378     }
00379     if( decode_gettag( ( const unsigned char * ) buffer, "call-id: ", callid ) == 0 ) {
00380         buffer[ 0 ] = 0;
00381         return NULL;
00382     }
00383     if( decode_gettag( ( const unsigned char * ) buffer, "cseq: ", cseq) == 0 ) {
00384         buffer[ 0 ] = 0;
00385         return NULL;
00386     }
00387     if( decode_gettag( ( const unsigned char * ) buffer, "via: ", via) == 0 ) {
00388         buffer[ 0 ] = 0;
00389         return NULL;
00390     }
00391  
00392     if (strlen(via) > 6) {
00393         if (strcasecmp(";rport",via+strlen(via)-6)==0) {
00394             via[strlen(via)-6] = 0;
00395         }
00396     }
00397     
00398     fill_random ( tag, 18 );
00399     
00400     snprintf(
00401         buffer, sizeof ( buffer ) - 1,
00402         "SIP/2.0 200 OK\r\n"    
00403         "To: %s;tag=%s\r\n"
00404         "From: %s\r\n"
00405         "Call-ID: %s\r\n"
00406         "CSeq: %s\r\n"
00407         "Via: %s\r\n"
00408         "Server: VZtech/pabxdriver-%s\r\n"
00409         "Content-Length: 0\r\n"
00410         "%s\r\n\r\n",
00411         to, tag, 
00412         from, 
00413         callid,
00414         cseq,
00415         via,
00416         SVNREV,
00417         SIP_ALLOW
00418     );
00419     
00420     return( buffer );
00421 }
00422 
00423 char * Sip::fill_random16h ( char * buffer )
00424 {
00425     fill_random( buffer, 16 );
00426     buffer[ 7 ] = '-';
00427     return( buffer );
00428 }
00429  
00430 char * Sip::fill_random ( char * buffer, const int size )
00431 {
00432     static uint16_t seed = time( NULL );
00433     seed += 1;
00434     srand( seed );
00435  
00436     for( int i = 0; i < size - 1; i++ )
00437     {
00438         buffer[ i ] = fill_random_aux[ rand() & 0x3f ];
00439     }
00440     
00441     buffer[ size - 1 ] = 0;
00442     return( buffer );
00443 }
00444  
00445 int Sip::get_cseq ( void )
00446 {
00447     static unsigned int cseq = 0;
00448     if( cseq == 0 )
00449     {
00450         /* initial value, random number */
00451         cseq = rand ();
00452         cseq &= 0x7fff;
00453     }
00454     cseq++;
00455     cseq &= 0x7fff;
00456     if ( cseq == 0 ) cseq++;
00457     return cseq;
00458 }
00459  
00460 char * Sip::decode_cseq ( const unsigned char * package, char * cseq )
00461 {
00462     char pkg [ SIP_MAXMSGSIZE ];
00463     
00464     if( decode_gettag ( package, "cseq: ", pkg ) != 0)
00465     {
00466         char cs [ SIP_MAXMSGSIZE ];
00467         
00468         int i = 0;
00469         strcpy ( cs, pkg );
00470         while ( ( cs [ i ] != 0 ) && ( cs [ i ] != ' ' ) ) i++;
00471         cs [ i ] = 0;
00472         strcpy ( cseq, cs );
00473     } else {
00474         cseq [ 0 ] = 0;
00475     }
00476     return ( cseq );
00477 }
00478  
00479 char * Sip::decode_branch ( const unsigned char * package, char * branch )
00480 {
00481     char pkg [ SIP_MAXMSGSIZE ];
00482     
00483     if ( decode_gettag ( package, "branch=", pkg ) != 0 )
00484     {
00485         int i = 0;
00486         strcpy ( branch, pkg );
00487         while ( ( branch [ i ] != 0 ) && ( branch [ i ] != ';' ) ) i++;
00488         branch [ i ] = 0;
00489     } else {
00490         branch [ 0 ] = 0;
00491     }
00492     
00493     return ( branch );
00494 }
00495 
00496 int Sip::decode_gettag ( const unsigned char * package, const char * tag, char * out )
00497 {
00498     int cmpsize = strlen ( tag );
00499     int size = strlen ( ( char * ) package ) - cmpsize;
00500     
00501     for ( int i = 0; i < size; i++ )
00502     {
00503         if ( strncasecmp( tag, ( char * ) package + i, cmpsize ) == 0 )
00504         {
00505             char * s;
00506             s = ( char * ) package + i + cmpsize;
00507             register int j = 0;
00508             while ( ( s [ j ] != '\r' ) && ( s [ j ] != '\n' ) ) j++;
00509             strncpy ( out, s, j ); // copy string to output
00510             out [ j ] = 0; // terminate string
00511             return 1; // found
00512         }
00513     }
00514     
00515     return 0; // not found
00516 }
00517 
00518 int Sip::fill_random_rtp_port ( void )
00519 {
00520     static uint16_t port = 0;
00521     port += 2;
00522     port &= 0x7fe; // 0 to 2046, always even
00523     return port + 16384;
00524 }
00525 
00526 void Sip::set_server_port ( const int new_server_port ) { this->server_port = new_server_port; }
00527 
00528 void Sip::set_server_ext ( const int new_server_ext ) { this->peer_ext = new_server_ext; }
00529 
00530 void Sip::set_server_ip ( const char * new_server_ip )
00531 {
00532     strncpy( this->server_ip, new_server_ip, 20 );
00533     this->server_ip[19] = 0;
00534 }
00535 
00536 /*  Retorna 
00537     = 0 :: ok
00538     < 0 :: tive problemas
00539     > 0 :: devo remover essa call do vetor de calls 
00540 */
00541 int Sip::listen_SIP_server ( void )
00542 {
00543     int ret = listen_SIP_server_return;
00544     listen_SIP_server_return = 0;
00545     return ret;
00546 }
00547 
00548 void Sip::set_port ( const int port ) { my_port = port; }
00549 
00550 void Sip::send_bye ( void )
00551 {
00552     build_bye_package ();
00553     
00554     int send = sock.sendTo ( sip_server, this -> buffer, strlen( this -> buffer ) );
00555     
00556     // antigo if ( debug_sip ) vz_debug ( "[%d] sizeof( bye pkg ) :: %d", this -> my_ext, strlen ( this -> buffer ) );
00557     if ( debug_invite ) vz_debug ( "[%d] sizeof( bye pkg ) :: %d", this -> my_ext, strlen ( this -> buffer ) );
00558     
00559     if ( send not_eq strlen ( this->buffer ) )
00560     {
00561         if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- BYE, %d, %d", this -> my_ext, send, strlen ( this -> buffer ) );
00562         __reconnect__ ();
00563         miss_sip_bye_send_pkg ++;
00564     }
00565 }
00566 
00567 int Sip::get_status ( void ) { return this->status; }
00568 
00569 void Sip::sip_set_status ( const uint8_t status ) { this->status = status; }
00570 
00571 int Sip::get_socket_fd ( void ) { return sock.get_fd (); }
00572 
00573 int Sip::udp_incomming_pkg ( void )
00574 {
00575     Endpoint from;  
00576     
00577     int length = sock.receiveFrom ( from, buffer, sizeof( buffer ) );
00578     
00579     if ( memcmp( ( ( u8_t * )( &(from._remoteHost) ) ) + 2, ( ( u8_t * )( &(sip_server._remoteHost) ) ) + 2, 6 ) != 0 ) return 0;
00580     
00581     if ( length == -1 )
00582     {
00583         if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- UDP Incomming", get_ext () );
00584         __reconnect__ ();
00585         miss_sip_inc_pkg ++;
00586     }
00587     
00588     if ( length > 0 )
00589     {
00590         if ( sizeof( buffer ) > length ) buffer[ length ] = 0;
00591         
00592         int sip_response = -1;
00593         
00594         // faster than atoi() (: 
00595         if ( buffer[ 7 ] == ' ' || buffer[ 11 ] == ' ' ){
00596             sip_response = ( buffer[ 8 ] - '0' ) * 100 + ( buffer[ 9 ] - '0' ) * 10 + ( buffer[ 10 ] - '0' );
00597         }
00598         
00599         if ( ( status == sip_trying ) || ( status == sip_ringing ) || ( status == sip_waiting_trying ) || ( status == sip_on_call ) )
00600         { 
00601             if ( sip_response == 200 ){ // Ok    
00602                 char *ref = strstr( buffer, "audio" );
00603                 
00604                 if ( debug_invite ) vz_debug ("[%d] udp_incomming_pkg -- ok", this->my_ext );
00605                 
00606                 if ( ref != NULL )
00607                 {
00608                     if ( drop_this_amount_of_ack_to_ast ) drop_this_amount_of_ack_to_ast--;
00609                         
00610                     if ( drop_this_amount_of_ack_to_ast )
00611                     {
00612                         vz_debug ("[%d] Droped ok pkg received from ast (%d)", this->my_ext, drop_this_amount_of_ack_to_ast );
00613                         return -71;    
00614                     }
00615                                         
00616                     ref += 6; // audio 
00617                     ref = strtok( ref, " ");
00618                     if ( call == NULL ){
00619                         call = new VZ_call ( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
00620                         if ( debug_alloc_vz_call ) vz_debug ( "VZ_Call :: %p", call );
00621                         if ( debug_rtp ) vz_debug ("[%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 );
00622                         if ( call == NULL ) memory_is_over = true;
00623                     }
00624             
00625                     build_ack_package ();
00626                     
00627                     int send = 0;
00628                     
00629                     if ( drop_ack_pkg )
00630                     {
00631                         vz_debug ("[%d] Droped ack pkt to ast", this->my_ext );
00632                     }
00633                         else
00634                     {
00635                         send = sock.sendTo ( sip_server, this -> buffer, strlen ( this -> buffer ) );
00636                     
00637                         if ( send not_eq strlen( this -> buffer ) )
00638                         {
00639                             if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- Ok -- Call mode on", this->my_ext );
00640                             __reconnect__ ();
00641                             miss_sip_ok_send_pkg ++;
00642                         }
00643                     }
00644                     
00645                     if ( debug_invite ) vz_debug ("[%d] Call alocada -- sizeof( ack ) :: %d - strlen( this -> buffer ):: %d", this->my_ext, send, strlen( this -> buffer ) );
00646                     sip_set_status ( sip_on_call );
00647                 }
00648             }
00649         }
00650         if ( ( status == sip_trying ) || ( status == sip_ringing ) )
00651         {
00652             if ( sip_response >= 400 && sip_response < 700 )
00653             {
00654                 if ( debug_invite ) { 
00655                     buffer [ 11 ] = 0; 
00656                     if ( debug_invite ) vz_debug ("[%d] Busy Here :: %s", this -> my_ext, buffer + 8 );
00657                 }
00658                 send_bye ();
00659                 sip_set_status ( sip_busy );
00660                 return ( NULL );  
00661             }
00662                 else if ( sip_response == 183 ) // Session in Progress
00663             {
00664                 char *ref = strstr ( buffer, "audio" );
00665                 if ( ref != NULL )
00666                 {
00667                     ref += 6; // strlen( "audio" ) == 6
00668                     ref = strtok( ref, " ");
00669                     if ( call == NULL )
00670                     {
00671                         this->call = new VZ_call ( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
00672                         if ( debug_alloc_vz_call ) vz_debug ( "VZ_Call :: %p", this->call );
00673                         if ( debug_rtp ) vz_debug ("[%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 );
00674                         if ( call == NULL ) memory_is_over = true;
00675                     }
00676                     waiting = true;
00677                 }
00678             }
00679         }
00680         
00681         if ( status == sip_trying ){
00682             if ( sip_response == 180 ){
00683                 if ( debug_invite ) vz_debug ("[%d] ringing", this->my_ext );
00684                 sip_set_status ( sip_ringing );
00685             }
00686         }
00687         
00688         if ( status == sip_waiting_trying ){
00689             if ( sip_response == 100 ){
00690                 if ( debug_invite ) vz_debug ("[%d] trying", this->my_ext )
00691                 sip_set_status ( sip_trying );
00692             }
00693         }
00694         
00695         if ( status == sip_on_call )
00696         {
00697             if ( !( strncasecmp( buffer, "bye ", 4 ) ) )
00698             {   
00699                 build_reply_package ();
00700                 
00701                 int send = sock.sendTo ( sip_server, this -> buffer, strlen ( this -> buffer ) );
00702                 if ( send not_eq strlen ( this -> buffer ) )
00703                 {
00704                     if ( debug_reconnect ) vz_debug (""
00705                         "[%d] Reconnect SIP -- RCV BYE from * -- ( expected, realized ) ( %d, %d )", 
00706                         this -> my_ext, strlen ( this -> buffer ), send 
00707                     );
00708                     
00709                     __reconnect__ ();
00710                     miss_sip_rcv_bye_send_pkg ++;
00711                 }
00712                 
00713                 if ( debug_invite ) vz_debug (""
00714                     "[%d] Bye request received from * - sizeof ( bye reply pkg ) :: %d", 
00715                     this -> my_ext, strlen ( this -> buffer ) 
00716                 );
00717                 
00718                 set_sip_rtp_port ( 0 );
00719                 
00720                 listen_SIP_server_return = my_ext;
00721             }
00722         }
00723     }
00724     
00725     return length;
00726 }
00727 
00728 void Sip::reset_call ( void ) { if( call != NULL ) call = NULL; }
00729 
00730 int Sip::get_ext ( void ) { return my_ext; }
00731 
00732 int Sip::get_port ( void ) { return my_port; }
00733 
00734 int Sip::get_sip_rtp_port ( void ) { return my_rtp_port; }
00735 
00736 void Sip::set_sip_rtp_port ( const int new_my_rtp_port )
00737 { 
00738     this->my_rtp_port = new_my_rtp_port; 
00739     if ( debug_rtp ) vz_debug ( "[%d] this->my_rtp_port ( %d ) = new_my_rtp_port( %d )", this->my_ext, this->my_rtp_port, new_my_rtp_port );
00740 }
00741 
00742 int Sip::print_yourself ( void )
00743 {
00744     vz_printf ("\r\n");
00745     vz_printf ("Values ::\r\n");
00746     vz_printf ("server_ip :: %s", server_ip );
00747     vz_printf ("server_port :: %d", server_port );
00748     vz_printf ("my_ip :: %s", my_ip );
00749     vz_printf ("my_port :: %d", my_port );
00750     vz_printf ("my_ext :: %d", my_ext );
00751     vz_printf ("my_rtp_port :: %d", my_rtp_port );
00752     vz_printf ("my_display :: %s", my_display );
00753     vz_printf ("peer_ext :: %d", peer_ext );
00754     vz_printf ("fill_random_aux :: %s", fill_random_aux );
00755     vz_printf ("last_invite_tag :: %s", last_invite_tag );
00756     vz_printf ("last_invite_callid :: %s", last_invite_callid );
00757     vz_printf ("SVNREV :: %s", SVNREV );
00758     vz_printf ("char buffer[ 1024 ] :: %p", ( void * ) buffer );
00759     
00760     //FIXME esse tipo de tag existe como metalinguagem ???
00761     //TOTHINK o que fazer pra entender melhor o estado dos sockets
00762     vz_printf ("UDPSocket sock :: %p", ( void * ) &sock );
00763     vz_printf ("Endpoint sip_server :: %p", ( void * ) &sip_server );
00764     
00765     vz_printf ("call :: %p", ( void * ) call );
00766     vz_printf ("invite_timer :: %d", ( int ) invite_timer.read () );
00767     vz_printf ("waiting ::  %s", ( waiting ) ? "true" : "false" );
00768     vz_printf ("listen_SIP_server_return :: %d", listen_SIP_server_return );
00769     vz_printf ("\r\n");
00770 
00771     return ( sizeof( Sip ) );    
00772 }
00773 
00774 int Sip::retry_send_last_invite_pkg_to_ast ( void )
00775 {
00776     char callbox_string [ 32 ];
00777     snprintf ( callbox_string, sizeof ( callbox_string ) -1, "%i", my_ext );
00778     
00779     int cseq = 0;
00780 
00781     call = NULL;
00782 
00783     build_invite_package ( &cseq, true );
00784     
00785     if ( debug_invite ) vz_debug ("cseq::%d", cseq );
00786     
00787     int send = 0;
00788     
00789     if ( drop_invite_to_ast_pkg )
00790     {
00791             vz_debug ("[%d] Droped invite pkg to ast", this->my_ext );
00792     }
00793         else
00794     {
00795         
00796         send = sock.sendTo ( sip_server, buffer, strlen ( buffer ) );
00797         
00798         if ( send not_eq strlen ( buffer ) )
00799         {
00800             if ( debug_reconnect ) vz_debug ("[%d] Reconnect SIP -- Invite", this->my_ext );
00801             __reconnect__ ();
00802             miss_sip_invite_send_pkg ++;
00803         }
00804      
00805         if ( debug_invite || debug_reconnect ) vz_debug ("[%d] Return value for invite pkg %d", this->my_ext, send );
00806     }
00807     
00808     return ( send );
00809 }
00810 
00811 void Sip::update ( void )
00812 {
00813     cm -> get_server_ip ( this -> server_ip );
00814     
00815     this -> server_port = cm -> get_server_port ();
00816     
00817     cm -> get_header_ip ( this -> my_ip );
00818     
00819     this -> peer_ext = cm -> get_server_ext ();
00820     
00821     sip_server.set_address ( this -> server_ip , this -> server_port );
00822     
00823     __reconnect__ ();
00824 }