Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface NTPClient mbed-rtos mbed
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 }
Generated on Fri Jul 22 2022 09:19:18 by
1.7.2