VZTECH / Mbed 2 deprecated header_main_publish

Dependencies:   EthernetInterface NTPClient mbed-rtos_old mbed

Fork of header_main_public by VZTECH

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