VZTECH / Mbed 2 deprecated header_main

Dependencies:   EthernetInterface NTPClient mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sip.cpp Source File

sip.cpp

00001 #include "sip.h"
00002 #include "utils.h"
00003 
00004 void Sip::__init_sock__( void ){
00005     sip_server.set_address( this->server_ip , this->server_port );
00006     sock.set_blocking( false, 1 ); // verificar isso com mais cuidado depois
00007     sock.bind( this->my_port );
00008     sock.init();
00009 }
00010 
00011 void Sip::__end_sock__(){
00012     sock.close(); 
00013 }
00014 
00015 Sip::Sip( char * server_ip, int server_port, char * my_ip, int my_port, int my_ext, int peer_ext, int id ){
00016     this->id = id;
00017     strncpy( this->server_ip, server_ip, 20 );
00018     this->server_ip[19] = 0;
00019     this->server_port = server_port;
00020     strncpy( this->my_ip, my_ip, 20 );
00021     this->my_ip[19] = 0;
00022     this->my_port = my_port;
00023     this->my_rtp_port = fill_random_rtp_port();
00024     this->my_ext = my_ext;
00025     itoa( this->my_ext, this->my_display, 10 );
00026     this->peer_ext = peer_ext;
00027  
00028     strcpy( this->fill_random_aux, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789pP" );
00029     strcpy( this->last_invite_tag, "" );
00030     strcpy( this->last_invite_callid, "");
00031     strcpy( this->SVNREV, "COLA" );
00032     status = sip_idle;
00033     
00034     __init_sock__();
00035 }
00036  
00037 Sip::Sip(){
00038     this->id = __MY_EXT__;
00039     strncpy( this->server_ip, __SEVER_IP__, 20 );
00040     this->server_ip[19] = 0;
00041     this->server_port = __SERVER_PORT__;
00042     strncpy( this->my_ip, __MY_IP__, 20 );
00043     this->my_ip[19] = 0;
00044     this->my_port = __MY_PORT__;
00045     this->my_rtp_port = fill_random_rtp_port();
00046     this->my_ext = __MY_EXT__;
00047     itoa( this->my_ext, this->my_display, 10 );
00048     this->peer_ext = __PEER_EXT__;
00049  
00050     strcpy( this->fill_random_aux, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789pP" );
00051     strcpy( this->last_invite_tag, "" );
00052     strcpy( this->last_invite_callid, "");
00053     strcpy( this->SVNREV, "COLA" );
00054     status = sip_idle;
00055     
00056     __init_sock__();
00057 }
00058  
00059 Sip::Sip( int id, uint16_t my_port ){
00060     this->id = id;
00061     strncpy( this->server_ip, __SEVER_IP__, 20 );
00062     this->server_ip[19] = 0;
00063     this->server_port = __SERVER_PORT__;
00064     strncpy( this->my_ip, __MY_IP__, 20 );
00065     this->my_ip[19] = 0;
00066     this->my_port = my_port;
00067     this->my_rtp_port = fill_random_rtp_port();
00068     this->my_ext = id;
00069     itoa( this->my_ext, this->my_display, 10 );
00070     this->peer_ext = __PEER_EXT__;
00071  
00072     strcpy( this->fill_random_aux, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789pP" );
00073     strcpy( this->last_invite_tag, "" );
00074     strcpy( this->last_invite_callid, "");
00075     strcpy( this->SVNREV, "COLA" );
00076     status = sip_idle;
00077     
00078     __init_sock__();
00079 }
00080  
00081 Sip::Sip( int id, uint16_t my_port, int dest_ext  ){
00082     this->id = id;
00083     strncpy( this->server_ip, __SEVER_IP__, 20 );
00084     this->server_ip[19] = 0;
00085     this->server_port = __SERVER_PORT__;
00086     strncpy( this->my_ip, __MY_IP__, 20 );
00087     this->my_ip[19] = 0;
00088     this->my_port = my_port;
00089     this->my_rtp_port = fill_random_rtp_port();
00090     this->my_ext = id;
00091     itoa( this->my_ext, this->my_display, 10 );
00092     this->peer_ext = dest_ext;
00093  
00094     strcpy( this->fill_random_aux, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789pP" );
00095     strcpy( this->last_invite_tag, "" );
00096     strcpy( this->last_invite_callid, "");
00097     strcpy( this->SVNREV, "COLA" );
00098     status = sip_idle;
00099     
00100     __init_sock__();
00101 }
00102  
00103 Sip::~Sip(){
00104     __end_sock__();
00105 }
00106  
00107 void Sip::registry(){
00108     char out[ 1000 ];
00109     build_registry_package( buffer );
00110     sock.sendTo( sip_server, buffer, sizeof( buffer ) );
00111     sock.receiveFrom( sip_server, buffer, sizeof( buffer ) );
00112     if( decode_gettag( (unsigned char *)buffer, "cseq: ", out ) ){
00113         if(strlen( out ) > 7){
00114             if(strcasecmp("options",out+strlen(out)-7) == 0){
00115                 char ans[ 2000 ];
00116                 build_reply_package( ans, (unsigned char*)buffer );
00117                 sock.sendTo( sip_server, ans, sizeof( ans ) );
00118             }
00119         }
00120     }
00121 }
00122 
00123 VZ_call * Sip::old_invite(){
00124     Timer t;
00125     char buffer[ 1024 ];
00126     char callbox_string[ 32 ];
00127     itoa( get_id(), callbox_string, 10 );
00128     int cseq;
00129  
00130     build_invite_package( buffer, callbox_string, &cseq );
00131     sock.sendTo( sip_server, buffer, sizeof( buffer ) );
00132  
00133     t.start();
00134     while( sock.receiveFrom( sip_server, buffer, sizeof( buffer ) ) < 1 ) {
00135         if( t.read() > __INVITE_MAX_WAITING_TIME__ ) { /* Trying package */
00136             change_sip_server();
00137             t.reset();
00138             break;
00139         }
00140     }
00141     while( sock.receiveFrom( sip_server, buffer, sizeof( buffer ) ) < 1 ) {
00142         if( t.read() > __INVITE_MAX_WAITING_TIME__ ) { /* Ringing package */
00143             change_sip_server();
00144             t.reset();
00145             break;
00146         }
00147     }
00148     int call_trying = 1;
00149     while( call_trying-- ){
00150         while( sock.receiveFrom( sip_server, buffer, sizeof( buffer ) ) < 1 ) {
00151             if( t.read() > __INVITE_MAX_WAITING_TIME__ ) { /* ok package */
00152                 change_sip_server();
00153                 t.reset();
00154                 break;
00155             }
00156         }
00157         wait( 3 );
00158         char * ref = strstr( buffer, "audio" );
00159         if( ref != NULL ){
00160             ref += 6; /*audio */
00161             ref = strtok( ref, " ");
00162             VZ_call * call = new VZ_call( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
00163             char ans[ 1024 ];
00164             build_ack_package( ans, ( unsigned char *)buffer );
00165             sock.sendTo( sip_server, ans, sizeof( ans ) );
00166             
00167             return( call );
00168         }
00169     }
00170     return( NULL );
00171 }
00172 
00173 VZ_call * Sip::invite(){
00174     Timer t;
00175     char callbox_string[ 32 ];
00176     itoa( get_id(), callbox_string, 10 );
00177  
00178     if( status != sip_on_call ) set_status(status, sip_waiting_trying );
00179     
00180     else return( NULL );
00181     
00182     int cseq = 0;
00183  
00184     build_invite_package( buffer, callbox_string, &cseq );
00185     sock.sendTo( sip_server, buffer, sizeof( buffer ) );
00186  
00187     debug_msg( "Inicio do invite" );
00188     debug_msg( "Sip::status::%d", status );
00189     t.start();
00190 
00191     sock.set_blocking( false, 5 );
00192     
00193     char buffer_eth_invite[ 1024 ];
00194     int loop_times = 0;
00195     int received_loop_times = 0;
00196     Timer reconnect;
00197     reconnect.start();
00198     static int id_ = 0;
00199     int length = 0;
00200     bool print = false;
00201     while( t.read() < __INVITE_MAX_WAITING_TIME__ ){    
00202         loop_times++;        
00203         length = sock.receiveFrom( sip_server, buffer_eth_invite, sizeof( buffer_eth_invite ) );
00204         if( length > 0 ){
00205             reconnect.reset();
00206             debug_msg("Pacotes recebidos :: %d", id_ );
00207             buffer_eth_invite[ length ] = 0;
00208             debug_msg("-- %d :: %s --", id_++, buffer_eth_invite );
00209             received_loop_times++;
00210             if( ( status == sip_trying ) || ( status == sip_ringing ) ){            
00211                 if( !( strncasecmp( buffer_eth_invite + 12, "ok", strlen("ok") ) ) ){
00212                     // tratar depois o esquema do Cseq ::
00213                     debug_msg( "Cseq == %d", cseq );
00214                     set_status(status, sip_on_call);
00215                     char *ref = strstr( buffer_eth_invite, "audio" );
00216                     debug_msg("ok");
00217                     if( ref != NULL ){
00218                         ref += 6; // audio 
00219                         ref = strtok( ref, " ");
00220                         VZ_call * call = new VZ_call( this->my_ext, this->my_rtp_port, this->peer_ext, atoi( ref ) );
00221                         char ans[ 1024 ];
00222                         build_ack_package( ans, ( unsigned char *)buffer_eth_invite );
00223                         sock.sendTo( sip_server, ans, sizeof( ans ) );
00224                         debug_msg("Call alocada -- Sip::status::%d -- loop_times :: %d :: received_loop_times :: %d", status, loop_times, received_loop_times );
00225                         set_status( status, sip_on_call );
00226                         return( call );
00227                     }
00228                 }
00229             }
00230             if( status == sip_trying ){
00231                 if( !( strncasecmp( buffer_eth_invite + 12, "ringing", strlen("ringing") ) ) ){
00232                     debug_msg("ringing");
00233                     t.reset();
00234                     set_status( status, sip_ringing );
00235                 }
00236             }
00237             if( status == sip_waiting_trying ){
00238                 if( !( strncasecmp( buffer_eth_invite + 12, "trying", strlen("trying") ) ) ){
00239                     debug_msg("trying")
00240                     t.reset();
00241                     set_status( status, sip_trying );
00242                 }
00243             }
00244         }else if( reconnect.read() > 4 ){
00245             sock.close();
00246             sock.bind( this->my_port );
00247             sock.init();
00248             sock.set_blocking( false, 1 );
00249             debug_msg("Reconnect");
00250             reconnect.reset();
00251             //sock.sendTo( sip_server, buffer, sizeof( buffer ) );
00252             led4 = !led4;
00253             print = true;
00254         }
00255         if( print ) debug_msg( "Lidos : %d --", length );
00256     }
00257     
00258     debug_msg("Call nao alocada -- Sip::status::%d -- loop_times :: %d :: received_loop_times :: %d", status, loop_times, received_loop_times );
00259     if( t.read() > __INVITE_MAX_WAITING_TIME__ ){
00260         set_status(status, sip_denied);
00261     }
00262     return( NULL );
00263 }
00264  
00265 char * Sip::build_registry_package( char * buffer ){
00266     char branch[ SIP_MAXFIELDSIZE ];
00267     char tag[ SIP_MAXFIELDSIZE ];
00268     char callid[ SIP_MAXFIELDSIZE ];
00269     fill_random16h( branch );
00270     fill_random( tag, 18 );
00271     fill_random16h( callid );
00272     char itoa_buffer[ 65 ];
00273     strcpy( buffer, "REGISTER sip:" );
00274     strcat( buffer, server_ip );
00275     strcat( buffer, ":" );
00276     itoa( server_port, itoa_buffer, 10 );
00277     strcat( buffer, itoa_buffer );
00278     strcat( buffer, " SIP/2.0\r\nVia: SIP/2.0/UDP " );
00279     strcat( buffer, my_ip );
00280     strcat( buffer, ":" );
00281     itoa( my_port, itoa_buffer, 10 );
00282     strcat( buffer, itoa_buffer );
00283     strcat( buffer, ";branch=" );
00284     strcat( buffer, branch );
00285     strcat( buffer, "\r\nFrom: " );
00286     itoa( my_ext, itoa_buffer, 10 );
00287     strcat( buffer, itoa_buffer );
00288     strcat( buffer, " <sip:" );
00289     strcat( buffer, itoa_buffer );
00290     strcat( buffer, "@" ); 
00291     strcat( buffer, server_ip );
00292     strcat( buffer, ":" );
00293     itoa( server_port, itoa_buffer, 10 );
00294     strcat( buffer, itoa_buffer );
00295     strcat( buffer, ">;tag=" );
00296     strcat( buffer, tag );
00297     strcat( buffer, "\r\nTo: " );
00298     itoa( my_ext, itoa_buffer, 10 );
00299     strcat( buffer, itoa_buffer );
00300     strcat( buffer, " <sip:" );
00301     itoa( my_ext, itoa_buffer, 10 );
00302     strcat( buffer, itoa_buffer );
00303     strcat( buffer, "@" );
00304     strcat( buffer, server_ip );
00305     strcat( buffer, ":" );
00306     itoa( server_port, itoa_buffer, 10 );
00307     strcat( buffer, itoa_buffer );
00308     strcat( buffer, ">\r\nCall-ID: " );
00309     strcat( buffer, callid );
00310     strcat( buffer, "\r\nCSeq: " );
00311     itoa( get_cseq(), itoa_buffer, 10 );
00312     strcat( buffer, itoa_buffer );
00313     strcat( buffer, " REGISTER\r\n" );
00314     strcat( buffer, "Max-Forwards: " );
00315     itoa( 70, itoa_buffer, 10 );
00316     strcat( buffer, itoa_buffer );
00317     strcat( buffer, "\r\n" );
00318     
00319     strcat( buffer, "Contact: " );
00320     itoa( my_ext, itoa_buffer, 10 );
00321     strcat( buffer, itoa_buffer );
00322     strcat( buffer, " <sip:" );
00323     strcat( buffer, itoa_buffer );
00324     strcat( buffer, "@" );
00325     strcat( buffer, my_ip );
00326     strcat( buffer, ":" );
00327     itoa( server_port, itoa_buffer, 10 );
00328     strcat( buffer, itoa_buffer );
00329     strcat( buffer, ">;expires=120" );
00330     //itoa( 1200, itoa_buffer, 10 );
00331     //strcat( buffer, itoa_buffer );
00332     strcat( buffer, "\r\n" );
00333     
00334     strcat( buffer, "User-Agent: VZtech/pabxdriver-" );
00335     strcat( buffer, SVNREV );
00336     strcat( buffer, "\r\nContent-Length: 0\r\n" );
00337     strcat( buffer, SIP_ALLOW );
00338     strcat( buffer, "\r\n\r\n" );              
00339     buffer[ SIP_MAXMSGSIZE - 1 ] = 0;
00340     return buffer;
00341 }
00342  
00343 char * Sip::build_invite_package( char * pkg, char * callbox_string, int * cseq ){
00344     char header[ SIP_MAXMSGSIZE ], body[ SIP_MAXMSGSIZE ];
00345     char branch[ SIP_MAXFIELDSIZE ];
00346     char tag[ SIP_MAXFIELDSIZE ];
00347     char callid[ SIP_MAXFIELDSIZE ];
00348     char itoa_buffer[ 65 ];
00349     *cseq = get_cseq();
00350     fill_random16h( branch );
00351     fill_random( tag,18 );
00352     fill_random16h( callid );
00353  
00354     strcpy( last_invite_tag,tag );
00355     strcpy( last_invite_callid, callid );
00356     
00357     strcpy( header, "INVITE sip:" );
00358     itoa( this->peer_ext, itoa_buffer, 10 );
00359     strcat( header, itoa_buffer );
00360     strcat( header, "@" );
00361     strcat( header, this->server_ip );
00362     strcat( header, ":" );
00363     itoa( this->server_port, itoa_buffer, 10 );
00364     strcat( header, itoa_buffer );
00365     strcat( header, " SIP/" );
00366     itoa( 2, itoa_buffer, 10 );
00367     strcat( header, itoa_buffer );
00368     strcat( header, "." );
00369     itoa( 0, itoa_buffer, 10 );
00370     strcat( header, itoa_buffer );
00371     strcat( header, "\r\n" );
00372     strcat( header, "Via: SIP/" );
00373     itoa( 2, itoa_buffer, 10 );
00374     strcat( header, itoa_buffer );
00375     strcat( header, "." );
00376     itoa( 0, itoa_buffer, 10 );
00377     strcat( header, itoa_buffer );
00378     strcat( header, "/UDP"  );
00379     strcat( header, this->my_ip );
00380     strcat( header, ":" );
00381     itoa( this->my_port, itoa_buffer, 10 );
00382     strcat( header, itoa_buffer );
00383     strcat( header, ";branch="  );
00384     strcat( header, branch );
00385     strcat( header, "\r\n" );
00386     strcat( header, "From: " );
00387     strcat( header, callbox_string );
00388     strcat( header, " <sip:" );
00389     itoa( this->my_ext, itoa_buffer, 10 );
00390     strcat( header, itoa_buffer );
00391     strcat( header, "@" );
00392     strcat( header, this->server_ip );
00393     strcat( header, ":" );
00394     itoa( this->server_port, itoa_buffer, 10 );
00395     strcat( header, itoa_buffer );
00396     strcat( header, ">;tag=" );
00397     strcat( header, tag );
00398     strcat( header, "\r\n" );
00399     strcat( header, "To: <sip:" );
00400     itoa( this->peer_ext, itoa_buffer, 10 );
00401     strcat( header, itoa_buffer );
00402     strcat( header, "@" );
00403     strcat( header, this->server_ip );
00404     strcat( header, ":" );
00405     itoa( this->server_port, itoa_buffer, 10 );
00406     strcat( header, itoa_buffer );
00407     strcat( header, ">\r\n" );
00408     strcat( header, "Call-ID: " );
00409     strcat( header, callid );
00410     strcat( header, "@" );
00411     strcat( header, this->my_ip );
00412     strcat( header, "\r\n" );
00413     strcat( header, "CSeq: " );
00414     itoa( *cseq, itoa_buffer, 10 );
00415     strcat( header, itoa_buffer );
00416     strcat( header, " INVITE\r\n" );
00417     strcat( header, "Contact: " );
00418     itoa( this->my_ext, itoa_buffer, 10 );
00419     strcat( header, itoa_buffer );
00420     strcat( header, " <sip:" );
00421     itoa( this->my_ext, itoa_buffer, 10 );
00422     strcat( header, itoa_buffer );
00423     strcat( header, "@" );
00424     strcat( header, this->my_ip );
00425     strcat( header, ":" );
00426     itoa( this->my_port, itoa_buffer, 10 );
00427     strcat( header, itoa_buffer );
00428     strcat( header, ">\r\n" );
00429     strcat( header, "Max-Forwards: " );
00430     itoa( 20, itoa_buffer, 10 );
00431     strcat( header, itoa_buffer );
00432     strcat( header, "\r\n" );
00433     strcat( header, "User-Agent: VZtech/pabxdriver-" );
00434     strcat( header, SVNREV );
00435     strcat( header, "\r\n" );
00436     strcat( header, "Expires: " );
00437     itoa( 70, itoa_buffer, 10 );
00438     strcat( header, itoa_buffer );
00439     strcat( header, "\r\n" );
00440     strcat( header, SIP_ALLOW );
00441     strcat( header, "\r\n" );
00442     strcat( header, "Content-Type: application/sdp\r\n" );
00443     header[ SIP_MAXMSGSIZE - 1 ] = 0;
00444     
00445     strcpy( body, "v=0\r\n" );
00446     strcat( body, "o=- " );
00447     itoa( 7377, itoa_buffer, 10 );
00448     strcat( body, itoa_buffer );
00449     strcat( body, " " );
00450     itoa( 18176, itoa_buffer, 10 );
00451     strcat( body, itoa_buffer );
00452     strcat( body, " IN IP" );
00453     itoa( 4, itoa_buffer, 10 );
00454     strcat( body, itoa_buffer );
00455     strcat( body, " " );
00456     strcat( body, this->my_ip );
00457     strcat( body, "\r\n" );
00458     strcat( body, "s=-\r\n" );
00459     strcat( body, "c=IN IP" );
00460     itoa( 4, itoa_buffer, 10 );
00461     strcat( body, itoa_buffer );
00462     strcat( body, " " );
00463     strcat( body, this->my_ip );
00464     strcat( body, "\r\n" );
00465     strcat( body, "t=" );
00466     itoa( 0, itoa_buffer, 10 );
00467     strcat( body, itoa_buffer );
00468     strcat( body, " " );
00469     itoa( 0, itoa_buffer, 10 );
00470     strcat( body, itoa_buffer );
00471     strcat( body, "\r\n" );
00472     strcat( body, "m=audio " );
00473     itoa( this->my_rtp_port, itoa_buffer, 10 );
00474     strcat( body, itoa_buffer );
00475     strcat( body, " RTP/AVP " );
00476     itoa( 8, itoa_buffer, 10 );
00477     strcat( body, itoa_buffer );
00478     strcat( body, " " );
00479     itoa( 101, itoa_buffer, 10 );
00480     strcat( body, itoa_buffer );
00481     strcat( body, "\r\n" );
00482     strcat( body, "a=rtpmap:" );
00483     itoa( 8, itoa_buffer, 10 );
00484     strcat( body, itoa_buffer );
00485     strcat( body, " PCMA/" );
00486     itoa( 8000, itoa_buffer, 10 );
00487     strcat( body, itoa_buffer );
00488     strcat( body, "/" );
00489     itoa( 1, itoa_buffer, 10 );
00490     strcat( body, itoa_buffer );
00491     strcat( body, "\r\n" );
00492     strcat( body, "a=rtpmap:" );
00493     itoa( 101, itoa_buffer, 10 );
00494     strcat( body, itoa_buffer );
00495     strcat( body, " telephone-event/" );
00496     itoa( 8000, itoa_buffer, 10 );
00497     strcat( body, itoa_buffer );
00498     strcat( body, "\r\n" );
00499     strcat( body, "a=fmtp: " );
00500     itoa( 101, itoa_buffer, 10 );
00501     strcat( body, itoa_buffer );
00502     strcat( body, " " );
00503     itoa( 0, itoa_buffer, 10 );
00504     strcat( body, itoa_buffer );
00505     strcat( body, "-" );
00506     itoa( 11, itoa_buffer, 10 );
00507     strcat( body, itoa_buffer );
00508     body[ SIP_MAXMSGSIZE - 1 ] = 0;
00509  
00510     make_content_length( header, body, pkg );
00511     return( pkg );
00512 }
00513  
00514 char * Sip::make_content_length( char * header, char * body, char * pkg ){
00515     int size;
00516     char itoa_buffer[ 65 ];
00517     size = strlen( body );
00518     strcpy( pkg, header );
00519     strcat( pkg, "Content-Length: " );
00520     itoa( size, itoa_buffer, 10 );
00521     strcat( pkg, itoa_buffer );
00522     strcat( pkg, "\r\n\r\n" );
00523     strcat( pkg, body );
00524     pkg[ SIP_MAXMSGSIZE - 1 ] = 0;
00525     return pkg;
00526 }
00527  
00528 char * Sip::build_bye_package( char * buffer ){
00529     char branch[SIP_MAXFIELDSIZE];
00530     char tag[SIP_MAXFIELDSIZE];
00531     char itoa_buffer[ 65 ];
00532     fill_random16h(branch);
00533     fill_random(tag,18);
00534     
00535     strcpy( buffer, "BYE sip:" );
00536     itoa( this->peer_ext, itoa_buffer, 10 );
00537     strcat( buffer, itoa_buffer );
00538     strcat( buffer, "@" );
00539     strcat( buffer, this->server_ip );
00540     strcat( buffer, ":" );
00541     itoa( this->server_port, itoa_buffer, 10 );
00542     strcat( buffer, itoa_buffer );
00543     strcat( buffer, " SIP/2.0\r\n" );
00544     strcat( buffer, "Via: SIP/2.0/UDP " );
00545     strcat( buffer, this->my_ip );
00546     strcat( buffer, ":" );
00547     itoa( this->my_port, itoa_buffer, 10 );
00548     strcat( buffer, itoa_buffer );
00549     strcat( buffer, ";branch=" );
00550     strcat( buffer, branch );
00551     strcat( buffer, "\r\n" );
00552     strcat( buffer, "From: " );          
00553     itoa( this->my_ext, itoa_buffer, 10 );
00554     strcat( buffer, itoa_buffer );
00555     strcat( buffer, " <sip:" );
00556     itoa( this->my_ext, itoa_buffer, 10 );
00557     strcat( buffer, itoa_buffer );
00558     strcat( buffer, "@" );
00559     strcat( buffer, this->server_ip );
00560     strcat( buffer, ":" );
00561     itoa( this->server_port, itoa_buffer, 10 );
00562     strcat( buffer, itoa_buffer );
00563     strcat( buffer, ">;tag=" );
00564     strcat( buffer, last_invite_tag );
00565     strcat( buffer, "\r\n" );
00566     strcat( buffer, "To: <sip:" );
00567     itoa( this->peer_ext, itoa_buffer, 10 );
00568     strcat( buffer, itoa_buffer );
00569     strcat( buffer, "@" );
00570     strcat( buffer, this->server_ip );
00571     strcat( buffer, ":" );
00572     itoa( this->server_port, itoa_buffer, 10 );
00573     strcat( buffer, itoa_buffer );
00574     strcat( buffer, ">;tag=" );
00575     strcat( buffer, tag );
00576     strcat( buffer, "\r\n" );
00577     strcat( buffer, "Call-ID: " );
00578     strcat( buffer, last_invite_callid );
00579     strcat( buffer, "@" );
00580     strcat( buffer, this->my_ip );
00581     strcat( buffer, "\r\n" );
00582     strcat( buffer, "CSeq: " );
00583     itoa( get_cseq(), itoa_buffer, 10 );
00584     strcat( buffer, itoa_buffer );
00585     strcat( buffer, " BYE\r\n" );
00586     strcat( buffer, "Max-Forwards: 70\r\n" );
00587     strcat( buffer, "User-Agent: VZtech/pabxdriver-" );
00588     strcat( buffer, SVNREV );
00589     strcat( buffer, "\r\n" );          
00590     strcat( buffer, "Content-Length: 0\r\n\r\n" );
00591     return( buffer );
00592 }
00593 char * Sip::build_ack_package( char * buffer, unsigned char * orig ){
00594     char to[ SIP_MAXFIELDSIZE ];
00595     char from[ SIP_MAXFIELDSIZE ];
00596     char callid[ SIP_MAXFIELDSIZE ];
00597     char via[ SIP_MAXFIELDSIZE ];
00598     char branch[ SIP_MAXFIELDSIZE ];
00599     char cseq[ SIP_MAXFIELDSIZE ];
00600     char itoa_buffer[ 65 ];
00601     // FIXME confirmar se nao preciso converter todos os ints com itoa
00602     if( decode_gettag( orig, "to: ", to ) == 0) {
00603         buffer[ 0 ] = 0;
00604         return NULL;
00605     }
00606     if( decode_gettag( orig, "from: ", from ) == 0) {
00607         buffer[ 0 ] = 0;
00608         return NULL;
00609     }
00610     if( decode_gettag( orig, "call-id: ", callid ) == 0) {
00611         buffer[ 0 ] = 0;
00612         return NULL;
00613     }
00614     decode_branch( orig, branch );
00615     decode_cseq( orig, cseq );
00616  
00617     if( strlen( via ) > 6 ) {
00618         if( strcasecmp( ";rport", via+strlen( via )-6) == 0) {
00619             via[strlen(via)-6] = 0;
00620         }
00621     }
00622     strcpy( buffer, "ACK sip:" );
00623     itoa( this->peer_ext, itoa_buffer, 10 );
00624     strcat( buffer, itoa_buffer );
00625     strcat( buffer, "@" );
00626     strcat( buffer, this->server_ip );
00627     strcat( buffer, ":" );
00628     itoa( this->server_port, itoa_buffer, 10 );
00629     strcat( buffer, itoa_buffer );
00630     strcat( buffer, " SIP/2.0\r\n" );
00631     strcat( buffer, "Via: SIP/2.0/UDP " );
00632     strcat( buffer, this->my_ip );
00633     strcat( buffer, ":" );
00634     itoa( this->my_port, itoa_buffer, 10 );
00635     strcat( buffer, itoa_buffer );
00636     strcat( buffer, ";branch=" );
00637     strcat( buffer, branch );
00638     strcat( buffer, "\r\n" );
00639     strcat( buffer, "From: " );
00640     strcat( buffer, from );
00641     strcat( buffer, "\r\n" );
00642     strcat( buffer, "To: " );
00643     strcat( buffer, to );
00644     strcat( buffer, "\r\n" );
00645     strcat( buffer, "Call-ID: " );
00646     strcat( buffer, callid );
00647     strcat( buffer, "\r\n" );
00648     strcat( buffer, "CSeq: " );
00649     strcat( buffer, cseq );
00650     strcat( buffer, " ACK\r\n" );
00651     strcat( buffer, "Max-Forwards: 70\r\n" );
00652     strcat( buffer, "Contact: " );
00653     itoa( this->my_ext, itoa_buffer, 10 );
00654     strcat( buffer, itoa_buffer );
00655     strcat( buffer, " <sip:" );
00656     itoa( this->my_ext, itoa_buffer, 10 );
00657     strcat( buffer, itoa_buffer );
00658     strcat( buffer, "@" );
00659     strcat( buffer, this->my_ip );
00660     strcat( buffer, ":" );
00661     itoa( this->my_port, itoa_buffer, 10 );
00662     strcat( buffer, itoa_buffer );
00663     strcat( buffer, ">\r\n" );
00664     strcat( buffer, "User-Agent: VZtech/pabxdriver-" );
00665     strcat( buffer, SVNREV );
00666     strcat( buffer, "\r\n" );
00667     strcat( buffer, "Content-Length: 0\r\n\r\n" );
00668     buffer[SIP_MAXMSGSIZE-1] = 0;
00669     return( buffer );
00670 }
00671  
00672 int Sip::get_return_code( char * buffer ){
00673     char a[32];
00674     int i = 0, j;
00675     if( strncmp( "SIP/", buffer, 4 ) != 0 ) return 0;
00676     if( strlen( buffer ) < 32) return 0;
00677     strncpy( a, buffer, 31 );
00678     a[ 31 ] = 0;
00679     while ( a[ i ] > ' ') i++;
00680     j = i+i;
00681     while( (a[ j ] >= '0') && ( a[ j ] <= '9') ) j++;
00682     a[ j ] = 0;
00683     return atoi( a + i + 1 );
00684 }
00685  
00686 char * Sip::build_generic_reply_package(char * buffer, unsigned char * orig, char * tag){
00687     char to[ SIP_MAXFIELDSIZE ];
00688     char from[ SIP_MAXFIELDSIZE ];
00689     char callid[ SIP_MAXFIELDSIZE ];
00690     char cseq[ SIP_MAXFIELDSIZE ];
00691     char via[ SIP_MAXFIELDSIZE ];
00692  
00693     if( decode_gettag( orig, "to: ", to ) == 0) {
00694         buffer[0] = 0;
00695         return NULL;
00696     }
00697     if( decode_gettag( orig, "from: ", from ) == 0) {
00698         buffer[0] = 0;
00699         return NULL;
00700     }
00701     if( decode_gettag( orig, "call-id: ", callid ) == 0) {
00702         buffer[0] = 0;
00703         return NULL;
00704     }
00705     if( decode_gettag( orig, "cseq: ", cseq ) == 0) {
00706         buffer[0] = 0;
00707         return NULL;
00708     }
00709     if( decode_gettag( orig, "via: ", via ) == 0) {
00710         buffer[0] = 0;
00711         return NULL;
00712     }
00713  
00714     if (strlen(via) > 6) {
00715         if (strcasecmp(";rport",via+strlen(via)-6)==0) {
00716             via[strlen(via)-6] = 0;
00717         }
00718     }
00719  
00720     strcpy( buffer, "SIP/2.0 " );
00721     strcat( buffer, tag );
00722     strcat( buffer, "\r\n" );
00723     strcat( buffer, "To: " );
00724     strcat( buffer, to );
00725     strcat( buffer, "\r\n" );
00726     strcat( buffer, "From: " );
00727     strcat( buffer, from );
00728     strcat( buffer, "\r\n" );
00729     strcat( buffer, "Call-ID: " );
00730     strcat( buffer, callid );
00731     strcat( buffer, "\r\n" );
00732     strcat( buffer, "CSeq: " );
00733     strcat( buffer, cseq );
00734     strcat( buffer, "\r\n" );
00735     strcat( buffer, "Via: " );
00736     strcat( buffer, via );
00737     strcat( buffer, "\r\n" );
00738     strcat( buffer, "Server: VZtech/pabxdriver-" );
00739     strcat( buffer, SVNREV );
00740     strcat( buffer, "\r\n" );
00741     strcat( buffer, "Content-Length: 0\r\n\r\n" );
00742     buffer[ SIP_MAXMSGSIZE - 1 ] = 0;
00743     return( buffer );
00744 }
00745 char * Sip::build_trying_package( char * buffer, unsigned char * orig ){   
00746     // FIXME trocar 100 para itoa( 100 ... )
00747     build_generic_reply_package( buffer, orig, "100 Trying" );
00748     return( buffer );
00749 }
00750  
00751 char * Sip::build_busy_package( char * buffer, unsigned char * orig ){   
00752     // FIXME trocar 100 para itoa( 100 ... )
00753     build_generic_reply_package( buffer, orig, "486 Busy Here");
00754     return( buffer );
00755 }
00756 char * Sip::build_reply_package( char * buffer, unsigned char * orig ){
00757     char to[ SIP_MAXFIELDSIZE ];
00758     char from[ SIP_MAXFIELDSIZE ];
00759     char callid[ SIP_MAXFIELDSIZE ];
00760     char cseq[ SIP_MAXFIELDSIZE ];
00761     char via[ SIP_MAXFIELDSIZE ];
00762     char tag[ SIP_MAXFIELDSIZE ];
00763  
00764     if( decode_gettag( orig, "to: ", to ) == 0) {
00765         buffer[ 0 ] = 0;
00766         return NULL;
00767     }
00768     if( decode_gettag( orig, "from: ", from ) == 0) {
00769         buffer[ 0 ] = 0;
00770         return NULL;
00771     }
00772     if( decode_gettag( orig, "call-id: ", callid ) == 0 ) {
00773         buffer[ 0 ] = 0;
00774         return NULL;
00775     }
00776     if( decode_gettag( orig, "cseq: ", cseq) == 0 ) {
00777         buffer[ 0 ] = 0;
00778         return NULL;
00779     }
00780     if( decode_gettag( orig, "via: ", via) == 0 ) {
00781         buffer[ 0 ] = 0;
00782         return NULL;
00783     }
00784  
00785     if (strlen(via) > 6) {
00786         if (strcasecmp(";rport",via+strlen(via)-6)==0) {
00787             via[strlen(via)-6] = 0;
00788         }
00789     }
00790     fill_random(tag,18);
00791     
00792     strcpy( buffer, "SIP/2.0 200 OK\r\n" );
00793     strcat( buffer, "To: " );
00794     strcat( buffer, to );
00795     strcat( buffer, ";tag=" );
00796     strcat( buffer, tag );
00797     strcat( buffer, "\r\n" );
00798     
00799     strcat( buffer, "From: " );
00800     strcat( buffer, from );
00801     strcat( buffer, "\r\n" );
00802     
00803     strcat( buffer, "Call-ID: " );
00804     strcat( buffer, callid );
00805     strcat( buffer, "\r\n" );
00806     
00807     strcat( buffer, "CSeq: " );
00808     strcat( buffer, cseq );
00809     strcat( buffer, "\r\n" );
00810     
00811     strcat( buffer, "Via: " );
00812     strcat( buffer, via );
00813     strcat( buffer, "\r\n" );
00814     
00815     strcat( buffer, "Server: VZtech/pabxdriver-" );
00816     strcat( buffer, SVNREV );
00817     strcat( buffer, "\r\n" );
00818     strcat( buffer, "Content-Length: 0\r\n" );
00819     strcat( buffer, SIP_ALLOW );
00820     strcat( buffer, "\r\n\r\n" );
00821     
00822     buffer[ SIP_MAXMSGSIZE - 1 ] = 0;
00823     return( buffer );
00824 }
00825 char * Sip::fill_random16h(char * buffer ){
00826     fill_random( buffer, 16 );
00827     buffer[ 7 ] = '-';
00828     return( buffer );
00829 }
00830  
00831 char * Sip::fill_random( char * buffer, int size ){
00832     static uint16_t seed = time( NULL );
00833     seed += 1;
00834     srand( seed );
00835  
00836     int i;
00837     for (i=0; i<size; i++) {
00838         buffer[ i ] = fill_random_aux[ rand() & 0x3f ];
00839     }
00840     buffer[ size ] = 0;
00841     return( buffer );
00842 }
00843  
00844 int Sip::get_cseq( void ){
00845     static unsigned int cseq = 0;
00846     if( cseq == 0 ) {
00847         /* initial value, random number */
00848         cseq = rand();
00849         cseq &= 0x7fff;
00850     }
00851     cseq++;
00852     cseq &= 0x7fff;
00853     if( cseq == 0 ) cseq++;
00854     return cseq;
00855 }
00856  
00857 char * Sip::decode_cseq( unsigned char * package, char * cseq ){
00858     char pkg[ 2048 ], cs[ 2048 ];
00859     if( decode_gettag( package, "cseq: ", pkg ) != 0) {
00860         int i = 0;
00861         strcpy( cs, pkg );
00862         while( ( cs[ i ] != 0 ) && ( cs[ i ] != ' ' ) ) i++;
00863         cs[ i ] = 0;
00864         strcpy( cseq, cs );
00865     } else {
00866         cseq[ 0 ] = 0;
00867     }
00868     return( cseq );
00869 }
00870  
00871 char * Sip::decode_branch( unsigned char * package, char * branch ){
00872     char pkg[ 2048 ];
00873     if( decode_gettag( package, "branch=", pkg ) != 0 ) {
00874         int i = 0;
00875         strcpy( branch, pkg );
00876         while( ( branch[ i ] != 0 ) && ( branch[ i ] != ';' ) ) i++;
00877         branch[ i ] = 0;
00878     } else {
00879         branch[ 0 ] = 0;
00880     }
00881     return( branch );
00882 }
00883 int Sip::decode_gettag( unsigned char * package, char * tag, char * out ){
00884     int size, i, cmpsize;
00885     cmpsize = strlen( tag );
00886     size = strlen( ( char * )package )-cmpsize;
00887     for ( i=0; i<size; i++) {
00888         if( strncasecmp( tag, (char*)package+i, cmpsize ) == 0) {
00889             char * s;
00890             s = (char*)package+i+cmpsize;
00891             register int j = 0;
00892             while ((s[ j ] != '\r') && (s[ j ] != '\n')) j++;
00893             strncpy( out, s, j ); // copy string to output
00894             out[ j ] = 0; // terminate string
00895             return 1; // found
00896         }
00897     }
00898     return 0; // not found
00899 }
00900  
00901 int Sip::get_id( void ){
00902     return this->id;
00903 }
00904 int Sip::get_my_rtp_port( void ){
00905     return this->my_rtp_port;
00906 }
00907 inline int Sip::fill_random_rtp_port(){  
00908     // o range [ 16384 - 32767 ] eh configuravel no server
00909     return ( ( this->my_ext + 16384 ) > 32767 ) ? ( ( this->my_ext + 16384 ) % ( 32767 - 16384 ) + 16384 ) : this->my_ext + 16384;
00910 }
00911  
00912 void Sip::change_sip_server(){
00913     // just in case sip server don't answer, invite another server
00914     // mudar para os sets
00915     set_server_ip( get_next_server_ip( this->buffer) );
00916     set_server_ext( get_next_server_ext() );
00917     set_server_port( get_next_server_port() );
00918     registry();
00919 }
00920  
00921 char * Sip::get_next_server_ip( char * server_ip ){
00922     strcpy( server_ip, this->server_ip );
00923     return server_ip;
00924 }
00925 int Sip::get_next_server_port(){
00926     return this->server_port;
00927 }
00928 int Sip::get_next_server_ext(){
00929     return this->peer_ext;
00930 }
00931 void Sip::set_server_port( int new_server_port ){
00932     this->server_port = new_server_port;
00933 }
00934 void Sip::set_server_ext( int new_server_ext ){
00935     this->peer_ext = new_server_ext;
00936 }
00937 void Sip::set_server_ip( char * new_server_ip ){
00938     strcpy( this->server_ip, new_server_ip );
00939     this->server_ip[19] = 0;
00940 }
00941 
00942 /*  Retorna 
00943     = 0 :: ok
00944     < 0 :: tive problemas
00945     > 0 :: devo remover essa call do vetor de calls 
00946 */
00947 int Sip::listen_SIP_server( void ){
00948     sock.set_blocking( false, 3 ); // verificar isso com mais cuidado depois
00949     uint8_t read = sock.receiveFrom( sip_server, this->buffer, sizeof( this->buffer ) );
00950     if( read > 0 ){
00951         debug_msg( "-- SIP recebeu algo --" );
00952         if( !( strncasecmp( buffer, "bye", strlen("bye") ) ) ){
00953             char ans[ 2000 ];
00954             build_reply_package( ans, (unsigned char*)buffer );
00955             sock.sendTo( sip_server, ans, sizeof( ans ) );
00956             
00957             debug_msg(" Server request BYE to %d ext", my_ext );
00958             return( this->my_ext );
00959         }else if( !( strncasecmp( buffer, "options", strlen("options") ) ) ){
00960             char ans[ 2000 ];
00961             debug_msg(" Options received ");
00962             build_reply_package( ans, (unsigned char*)buffer );
00963             sock.sendTo( sip_server, ans, sizeof( ans ) );
00964         }
00965     }
00966     return( 0 ); 
00967 }
00968 
00969 void Sip::set_ext( int ext ){
00970     my_ext = ext;
00971 }
00972 
00973 void Sip::set_port( int port ){
00974     my_port = port;
00975 }
00976 
00977 void Sip::send_bye( void ){
00978     build_bye_package( this->buffer );
00979     sock.sendTo( sip_server, build_bye_package( this->buffer ), sizeof( this->buffer ) );
00980 }
00981 
00982 void Sip::send_unregistry_pkg(){
00983     build_unregistry_package( this->buffer );
00984     for( register int i = 0; i < 7; i++ )
00985         sock.sendTo( sip_server, build_bye_package( this->buffer ), sizeof( this->buffer ) );
00986 }
00987 
00988 char * Sip::build_unregistry_package( char * buffer ){
00989     char branch[ SIP_MAXFIELDSIZE ];
00990     char tag[ SIP_MAXFIELDSIZE ];
00991     char callid[ SIP_MAXFIELDSIZE ];
00992     fill_random16h( branch );
00993     fill_random( tag, 18 );
00994     fill_random16h( callid );
00995     char itoa_buffer[ 65 ];
00996     strcpy( buffer, "REGISTER sip:" );
00997     strcat( buffer, server_ip );
00998     strcat( buffer, ":" );
00999     itoa( server_port, itoa_buffer, 10 );
01000     strcat( buffer, itoa_buffer );
01001     strcat( buffer, " SIP/2.0\r\nVia: SIP/2.0/UDP " );
01002     strcat( buffer, my_ip );
01003     strcat( buffer, ":" );
01004     itoa( my_port, itoa_buffer, 10 );
01005     strcat( buffer, itoa_buffer );
01006     strcat( buffer, ";branch=" );
01007     strcat( buffer, branch );
01008     strcat( buffer, "\r\nFrom: " );
01009     itoa( my_ext, itoa_buffer, 10 );
01010     strcat( buffer, itoa_buffer );
01011     strcat( buffer, " <sip:" );
01012     strcat( buffer, itoa_buffer );
01013     strcat( buffer, "@" ); 
01014     strcat( buffer, server_ip );
01015     strcat( buffer, ":" );
01016     itoa( server_port, itoa_buffer, 10 );
01017     strcat( buffer, itoa_buffer );
01018     strcat( buffer, ">;tag=" );
01019     strcat( buffer, tag );
01020     strcat( buffer, "\r\nTo: " );
01021     itoa( my_ext, itoa_buffer, 10 );
01022     strcat( buffer, itoa_buffer );
01023     strcat( buffer, " <sip:" );
01024     itoa( my_ext, itoa_buffer, 10 );
01025     strcat( buffer, itoa_buffer );
01026     strcat( buffer, "@" );
01027     strcat( buffer, server_ip );
01028     strcat( buffer, ":" );
01029     itoa( server_port, itoa_buffer, 10 );
01030     strcat( buffer, itoa_buffer );
01031     strcat( buffer, ">\r\nCall-ID: " );
01032     strcat( buffer, callid );
01033     strcat( buffer, "\r\nCSeq: " );
01034     itoa( get_cseq(), itoa_buffer, 10 );
01035     strcat( buffer, itoa_buffer );
01036     strcat( buffer, " REGISTER\r\n" );
01037     strcat( buffer, "Max-Forwards: " );
01038     itoa( 70, itoa_buffer, 10 );
01039     strcat( buffer, itoa_buffer );
01040     strcat( buffer, "\r\n" );
01041     
01042     strcat( buffer, "Contact: " );
01043     itoa( my_ext, itoa_buffer, 10 );
01044     strcat( buffer, itoa_buffer );
01045     strcat( buffer, " <sip:" );
01046     strcat( buffer, itoa_buffer );
01047     strcat( buffer, "@" );
01048     strcat( buffer, my_ip );
01049     strcat( buffer, ":" );
01050     itoa( server_port, itoa_buffer, 10 );
01051     strcat( buffer, itoa_buffer );
01052     strcat( buffer, ">;expires=0\r\n" );
01053     /*
01054     strcat( buffer, ">;expires=" );
01055     itoa( 0, itoa_buffer, 10 );
01056     strcat( buffer, itoa_buffer );
01057     strcat( buffer, "\r\n" );
01058     */
01059     
01060     strcat( buffer, "User-Agent: VZtech/pabxdriver-" );
01061     strcat( buffer, SVNREV );
01062     strcat( buffer, "\r\nContent-Length: 0\r\n" );
01063     strcat( buffer, SIP_ALLOW );
01064     strcat( buffer, "\r\n\r\n" );              
01065     buffer[ SIP_MAXMSGSIZE - 1 ] = 0;
01066     return buffer;
01067 }