![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
sip3_transmit.c File Reference
Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)
Definition in file sip3_transmit.c.
#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "sip3.h"
#include "sip3funcs.h"
Include dependency graph for sip3_transmit.c:

Go to the source code of this file.
Functions | |
| GNURK int | __transmit_response (struct sip_dialog *p, const char *msg, struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| static int | add_vidupdate (struct sip_request *req) |
| add XML encoded media control with update | |
| GNURK void | transmit_fake_auth_response (struct sip_dialog *p, struct sip_request *req, int reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
| GNURK int | transmit_info_with_digit (struct sip_dialog *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| GNURK int | transmit_info_with_vidupdate (struct sip_dialog *p) |
| Send SIP INFO with video update request. | |
| GNURK int | transmit_invite (struct sip_dialog *dialog, int sipmethod, int sdp, int init) |
| Build REFER/INVITE/OPTIONS message and transmit it. | |
| GNURK int | transmit_message_with_text (struct sip_dialog *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| GNURK int | transmit_notify_with_mwi (struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten) |
| Notify user of messages waiting in voicemail. | |
| GNURK int | transmit_refer (struct sip_dialog *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| GNURK int | transmit_reinvite_with_sdp (struct sip_dialog *p, int t38type) |
| Transmit reinvite with SDP. | |
| GNURK int | transmit_request (struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request. | |
| GNURK int | transmit_request_with_auth (struct sip_dialog *dialog, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| GNURK int | transmit_response (struct sip_dialog *p, const char *msg, struct sip_request *req) |
| Transmit response, no retransmits. | |
| GNURK int | transmit_response_reliable (struct sip_dialog *p, const char *msg, struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| GNURK int | transmit_response_with_attachment (enum responseattach attach, struct sip_dialog *p, const char *msg, struct sip_request *req, enum xmittype reliable) |
| Transmit responses with various attachments. | |
| GNURK int | transmit_response_with_auth (struct sip_dialog *p, const char *msg, struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| GNURK int | transmit_response_with_unsupported (struct sip_dialog *p, const char *msg, struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| GNURK int | transmit_sip_request (struct sip_dialog *p, struct sip_request *req) |
| Transmit SIP request unreliably (only used in sip_notify subsystem). | |
|
||||||||||||||||||||
|
Base transmit response function. Definition at line 113 of file sip3_transmit.c. References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), sip_request::data_size, get_header(), ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, sip_dialog::method, sip_dialog::owner, respprep(), send_response(), sip_request::seqno, SIP_INVITE, SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00114 { 00115 struct sip_request *resp; 00116 int seqno = 0; 00117 int res; 00118 00119 00120 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 00121 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 00122 return -1; 00123 } 00124 00125 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00126 ast_log(LOG_DEBUG, " :::: Response data size: %d\n", (int) resp->data_size); 00127 resp->seqno = seqno; 00128 respprep(resp, p, msg, req); 00129 add_header_contentLength(resp, 0); 00130 /* If we are cancelling an incoming invite for some reason, add information 00131 about the reason why we are doing this in clear text */ 00132 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 00133 char buf[10]; 00134 00135 add_header(resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 00136 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 00137 add_header(resp, "X-Asterisk-HangupCauseCode", buf); 00138 } 00139 res = send_response(p, resp, reliable); 00140 if (reliable == XMIT_UNRELIABLE) 00141 siprequest_free(resp); 00142 return res; 00143 }
|
|
|
add XML encoded media control with update
Definition at line 94 of file sip3_transmit.c. References add_header(), add_header_contentLength(), and add_line(). 00095 { 00096 const char *xml_is_a_huge_waste_of_space = 00097 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 00098 " <media_control>\r\n" 00099 " <vc_primitive>\r\n" 00100 " <to_encoder>\r\n" 00101 " <picture_fast_update>\r\n" 00102 " </picture_fast_update>\r\n" 00103 " </to_encoder>\r\n" 00104 " </vc_primitive>\r\n" 00105 " </media_control>\r\n"; 00106 add_header(req, "Content-Type", "application/media_control+xml"); 00107 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 00108 add_line(req, xml_is_a_huge_waste_of_space); 00109 return 0; 00110 }
|
|
||||||||||||||||
|
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 623 of file sip3_transmit.c. References ast_random(), ast_string_field_build, and transmit_response_with_auth(). 00624 { 00625 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 00626 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 00627 }
|
|
||||||||||||||||
|
Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
Definition at line 540 of file sip3_transmit.c. References add_digit(), reqprep(), send_request(), SIP_INFO, SIP_MAX_PACKET, sipnet, siprequest_alloc(), TRUE, and XMIT_RELIABLE. 00541 { 00542 struct sip_request *req; 00543 00544 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00545 reqprep(req, p, SIP_INFO, 0, TRUE); 00546 add_digit(req, digit, duration); 00547 return send_request(p, req, XMIT_RELIABLE); 00548 }
|
|
|
Send SIP INFO with video update request.
Definition at line 551 of file sip3_transmit.c. References add_vidupdate(), reqprep(), send_request(), SIP_INFO, SIP_MAX_PACKET, sipnet, siprequest_alloc(), TRUE, and XMIT_RELIABLE. 00552 { 00553 struct sip_request *req; 00554 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00555 00556 reqprep(req, p, SIP_INFO, 0, TRUE); 00557 add_vidupdate(req); 00558 return send_request(p, req, XMIT_RELIABLE); 00559 }
|
|
||||||||||||||||||||
|
Build REFER/INVITE/OPTIONS message and transmit it.
Definition at line 295 of file sip3_transmit.c. References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), build_via(), sip_request::dialog, initialize_initreq(), initreqprep(), LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, reqprep(), send_request(), SIP_MAX_PACKET, SIP_REFER, sipdebug, sipnet, siprequest_alloc(), siprequest_free(), SUPPORTED_EXTENSIONS, T38_LOCAL_DIRECT, TRUE, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE. 00296 { 00297 struct sip_request *req; 00298 int res; 00299 00300 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00301 req->method = sipmethod; 00302 if (init) 00303 /* Bump branch even on initial requests */ 00304 build_via(dialog, TRUE); 00305 00306 if (init == 2) /* open a new dialog */ 00307 initreqprep(req, dialog, sipmethod); 00308 else 00309 reqprep(req, dialog, sipmethod, 0, TRUE); 00310 00311 if (dialog->inviteoptions && dialog->inviteoptions->auth) 00312 add_header(req, dialog->inviteoptions->authheader, dialog->inviteoptions->auth); 00313 append_date(req); 00314 if (sipmethod == SIP_REFER && dialog->refer) { /* Call transfer */ 00315 char buf[BUFSIZ]; 00316 if (!ast_strlen_zero(dialog->refer->refer_to)) 00317 add_header(req, "Refer-To", dialog->refer->refer_to); 00318 if (!ast_strlen_zero(dialog->refer->referred_by)) { 00319 sprintf(buf, "%s <%s>", dialog->refer->referred_by_name, dialog->refer->referred_by); 00320 add_header(req, "Referred-By", buf); 00321 } 00322 } 00323 00324 if (dialog->inviteoptions && !ast_strlen_zero(dialog->inviteoptions->replaces)) { 00325 /* This new INVITE is part of an attended transfer. Make sure that the 00326 other end knows and replace the current call with this new call */ 00327 add_header(req, "Replaces", dialog->inviteoptions->replaces); 00328 add_header(req, "Require", "replaces"); 00329 } 00330 00331 add_header(req, "Allow", ALLOWED_METHODS); 00332 add_header(req, "Supported", SUPPORTED_EXTENSIONS); 00333 if (dialog->inviteoptions && dialog->inviteoptions->addsipheaders) { 00334 struct ast_channel *ast; 00335 struct varshead *headp = NULL; 00336 const struct ast_var_t *current; 00337 00338 ast = dialog->owner; /* The owner channel */ 00339 if (ast) { 00340 char *headdup; 00341 headp = &ast->varshead; 00342 if (!headp) 00343 ast_log(LOG_WARNING,"No varshead for the channel...ooops!\n"); 00344 else { 00345 AST_LIST_TRAVERSE(headp, current, entries) { 00346 /* SIPADDHEADER: Add SIP header to outgoing call */ 00347 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 00348 char *content, *end; 00349 const char *header = ast_var_value(current); 00350 00351 headdup = ast_strdupa(header); 00352 /* Strip of the starting " (if it's there) */ 00353 if (*headdup == '"') 00354 headdup++; 00355 if ((content = strchr(headdup, ':'))) { 00356 *content++ = '\0'; 00357 content = ast_skip_blanks(content); /* Skip white space */ 00358 /* Strip the ending " (if it's there) */ 00359 end = content + strlen(content) -1; 00360 if (*end == '"') 00361 *end = '\0'; 00362 00363 add_header(req, headdup, content); 00364 if (sipdebug) 00365 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 00366 } 00367 } 00368 } 00369 } 00370 } 00371 } 00372 if (sdp) { 00373 if (dialog->udptl && dialog->t38.state == T38_LOCAL_DIRECT) { 00374 ast_udptl_offered_from_local(dialog->udptl, 1); 00375 if (option_debug) 00376 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", dialog->t38.state, dialog->owner ? dialog->owner->name : "<none>"); 00377 add_t38_sdp(req, dialog); 00378 } else if (dialog->rtp) 00379 add_sdp(req, dialog); 00380 } else { 00381 add_header_contentLength(req, 0); 00382 } 00383 00384 if (!dialog->initreq) 00385 initialize_initreq(dialog, req); 00386 dialog->lastinvite = dialog->ocseq; 00387 res = send_request(dialog, req, init ? XMIT_CRITICAL : XMIT_RELIABLE); 00388 00389 if (!init) 00390 siprequest_free(req); 00391 00392 return res; 00393 }
|
|
||||||||||||
|
Transmit text with SIP MESSAGE method.
Definition at line 444 of file sip3_transmit.c. References add_text(), len, reqprep(), send_request(), SIP_MAX_PACKET, SIP_MESSAGE, sipnet, siprequest_alloc(), TRUE, and XMIT_RELIABLE. 00445 { 00446 struct sip_request *req; 00447 size_t len = SIP_MAX_PACKET; 00448 00449 /* If we have a very large text message, allocate enough memory for it 00450 We're guessing that the max size of headers is 500 bytes here. 00451 */ 00452 if (strlen(text) > (len - 500)) 00453 len += strlen(text); 00454 00455 req = siprequest_alloc(len, &sipnet); 00456 00457 reqprep(req, p, SIP_MESSAGE, 0, TRUE); 00458 add_text(req, text); 00459 return send_request(p, req, XMIT_RELIABLE); 00460 }
|
|
||||||||||||||||||||
|
Notify user of messages waiting in voicemail.
Definition at line 401 of file sip3_transmit.c. References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), sip_globals::default_notifymime, sip_globals::default_vmexten, sip_dialog::expiry, global, initialize_initreq(), sip_dialog::initreq, initreqprep(), LOG_WARNING, sip_dialog::ourip, S_OR, send_request(), SIP_MAX_PACKET, SIP_NOTIFY, sipnet, siprequest_alloc(), sip_dialog::subscribed, and XMIT_RELIABLE. 00402 { 00403 struct sip_request *req; 00404 char tmp[500]; 00405 char *t = tmp; 00406 size_t maxbytes = sizeof(tmp); 00407 00408 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00409 initreqprep(req, p, SIP_NOTIFY); 00410 add_header(req, "Event", "message-summary"); 00411 add_header(req, "Content-Type", global.default_notifymime); 00412 00413 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 00414 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 00415 S_OR(vmexten, global.default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 00416 ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs); 00417 if (p->subscribed) { 00418 if (p->expiry) 00419 add_header(req, "Subscription-State", "active"); 00420 else /* Expired */ 00421 add_header(req, "Subscription-State", "terminated;reason=timeout"); 00422 } 00423 00424 if (t > tmp + sizeof(tmp)) 00425 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 00426 00427 add_header_contentLength(req, strlen(tmp)); 00428 add_line(req, tmp); 00429 00430 if (!p->initreq) 00431 initialize_initreq(p, req); 00432 return send_request(p, req, XMIT_RELIABLE); 00433 }
|
|
||||||||||||
|
Transmit SIP REFER message (initiated by the transfer() dialplan application.
Definition at line 467 of file sip3_transmit.c. References add_header(), ALLOWED_METHODS, append_maxforwards(), ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_dialog::flags, sip_request::from, get_header(), get_in_brackets(), sip_request::headers, sip_dialog::initreq, LOG_DEBUG, LOG_NOTICE, option_debug, sip_dialog::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_MAX_PACKET, SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sipnet, siprequest_alloc(), sip_refer::status, SUPPORTED_EXTENSIONS, sip_dialog::tag, TRUE, and XMIT_RELIABLE. 00468 { 00469 struct sip_request *req; 00470 char from[256]; 00471 const char *of; 00472 char *c; 00473 char referto[256]; 00474 char *ttag, *ftag; 00475 char *theirtag = ast_strdupa(p->theirtag); 00476 00477 00478 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00479 req->headers = 0; 00480 00481 if (option_debug || sipdebug) 00482 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 00483 00484 /* Are we transfering an inbound or outbound call ? */ 00485 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 00486 of = get_header(p->initreq, "To"); 00487 ttag = theirtag; 00488 ftag = p->tag; 00489 } else { 00490 of = get_header(p->initreq, "From"); 00491 ftag = theirtag; 00492 ttag = p->tag; 00493 } 00494 00495 ast_copy_string(from, of, sizeof(from)); 00496 of = get_in_brackets(from); 00497 ast_string_field_set(p, from, of); 00498 if (strncmp(of, "sip:", 4)) 00499 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 00500 else 00501 of += 4; 00502 /* Get just the username part */ 00503 if ((c = strchr(dest, '@'))) 00504 c = NULL; 00505 else if ((c = strchr(of, '@'))) 00506 *c++ = '\0'; 00507 if (c) 00508 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 00509 else 00510 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 00511 00512 /* save in case we get 407 challenge */ 00513 sip_refer_allocate(p); 00514 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 00515 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 00516 p->refer->status = REFER_SENT; /* Set refer status */ 00517 00518 reqprep(req, p, SIP_REFER, 0, TRUE); 00519 append_maxforwards(req); 00520 00521 add_header(req, "Refer-To", referto); 00522 add_header(req, "Allow", ALLOWED_METHODS); 00523 add_header(req, "Supported", SUPPORTED_EXTENSIONS); 00524 if (!ast_strlen_zero(p->our_contact)) 00525 add_header(req, "Referred-By", p->our_contact); 00526 00527 return send_request(p, req, XMIT_RELIABLE); 00528 /* We should propably wait for a NOTIFY here until we ack the transfer */ 00529 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 00530 00531 /*! \todo In theory, we should hang around and wait for a reply, before 00532 returning to the dial plan here. Don't know really how that would 00533 affect the transfer() app or the pbx, but, well, to make this 00534 useful we should have a STATUS code on transfer(). 00535 */ 00536 }
|
|
||||||||||||
|
Transmit reinvite with SDP.
Definition at line 270 of file sip3_transmit.c. References add_header(), add_sdp(), add_t38_sdp(), ALLOWED_METHODS, append_history, ast_test_flag, sip_dialog::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_MAX_PACKET, SIP_NO_HISTORY, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, sipnet, siprequest_alloc(), SUPPORTED_EXTENSIONS, and XMIT_CRITICAL. 00271 { 00272 struct sip_request *req; 00273 00274 req = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00275 reqprep(req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 00276 00277 add_header(req, "Allow", ALLOWED_METHODS); 00278 add_header(req, "Supported", SUPPORTED_EXTENSIONS); 00279 if (sipdebug) 00280 add_header(req, "X-asterisk-Info",(t38type ? "SIP re-invite for T38 fax" : "SIP re-invite (External RTP bridge)")); 00281 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 00282 append_history(p, "ReInv", "%s", (t38type ? "Re-invite sent for T38" : "Re-invite sent for external RTP media")); 00283 if (t38type) 00284 add_t38_sdp(req, p); 00285 else 00286 add_sdp(req, p); 00287 00288 /* Use this as the basis */ 00289 initialize_initreq(p, req); 00290 p->lastinvite = p->ocseq; 00291 return send_request(p, req, XMIT_CRITICAL); 00292 }
|
|
||||||||||||||||||||||||
|
Transmit generic SIP request.
Definition at line 562 of file sip3_transmit.c. References add_header_contentLength(), reqprep(), send_request(), SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00563 { 00564 struct sip_request *resp; 00565 int res; 00566 00567 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00568 00569 reqprep(resp, p, sipmethod, seqno, newbranch); 00570 add_header_contentLength(resp, 0); 00571 res = send_request(p, resp, reliable); 00572 if (reliable == XMIT_UNRELIABLE) 00573 siprequest_free(resp); 00574 return res; 00575 }
|
|
||||||||||||||||||||||||
|
Transmit SIP request, auth added.
Definition at line 578 of file sip3_transmit.c. References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), auth_headers(), sip_invite_param::auth_type, build_reply_digest(), sip_request::dialog, ast_channel::hangupcause, sip_dialog::inviteoptions, LOG_ERROR, LOG_WARNING, sip_dialog::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00579 { 00580 struct sip_request *resp; 00581 int res; 00582 00583 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00584 if (!resp) { 00585 ast_log(LOG_ERROR, "--- Can't allocate SIP request for this transaction! Call ID %s\n", dialog->callid); 00586 } 00587 00588 reqprep(resp, dialog, sipmethod, seqno, newbranch); 00589 if (!ast_strlen_zero(dialog->realm)) { 00590 char digest[1024]; 00591 00592 memset(digest, 0, sizeof(digest)); 00593 if(!build_reply_digest(dialog, sipmethod, digest, sizeof(digest))) { 00594 char *dummy, *response; 00595 00596 enum sip_auth_type code = dialog->inviteoptions ? dialog->inviteoptions->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */ 00597 auth_headers(code, &dummy, &response); 00598 add_header(resp, response, digest); 00599 } else 00600 ast_log(LOG_WARNING, "No authentication available for call %s\n", dialog->callid); 00601 } 00602 /* If we are hanging up and know a cause for that, send it in clear text to make 00603 debugging easier. */ 00604 if (sipmethod == SIP_BYE && dialog->owner && dialog->owner->hangupcause) { 00605 char buf[10]; 00606 00607 add_header(resp, "X-Asterisk-HangupCause", ast_cause2str(dialog->owner->hangupcause)); 00608 snprintf(buf, sizeof(buf), "%d", dialog->owner->hangupcause); 00609 add_header(resp, "X-Asterisk-HangupCauseCode", buf); 00610 } 00611 00612 add_header_contentLength(resp, 0); 00613 00614 res = send_request(dialog, resp, reliable); 00615 if (reliable == XMIT_UNRELIABLE) 00616 siprequest_free(resp); 00617 return res; 00618 }
|
|
||||||||||||||||
|
Transmit response, no retransmits.
Definition at line 146 of file sip3_transmit.c. References __transmit_response(), and XMIT_UNRELIABLE. 00147 { 00148 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 00149 }
|
|
||||||||||||||||
|
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
Definition at line 155 of file sip3_transmit.c. References __transmit_response(), and XMIT_CRITICAL. 00156 { 00157 return __transmit_response(p, msg, req, XMIT_CRITICAL); 00158 }
|
|
||||||||||||||||||||||||
|
Transmit responses with various attachments.
Definition at line 161 of file sip3_transmit.c. References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), append_date(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, ast_udptl_offered_from_local(), sip_dialog::autoframing, expiry, sip_dialog::flags, LOG_DEBUG, LOG_ERROR, option_debug, sip_dialog::prefs, respprep(), sip_dialog::rtp, send_response(), sip_request::seqno, SIP_MAX_PACKET, SIP_OUTGOING, sipnet, siprequest_alloc(), siprequest_free(), try_suggested_sip_codec(), sip_dialog::udptl, WITH_ALLOW, WITH_DATE, WITH_MINEXPIRY, WITH_SDP, WITH_T38_SDP, and XMIT_UNRELIABLE. Referenced by handle_invite_replaces(), handle_request(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), register_verify(), sip_answer(), sip_handle_t38_reinvite(), sip_indicate(), and write_media_frame(). 00163 { 00164 struct sip_request *resp; 00165 char buf[12]; 00166 int res; 00167 00168 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00169 respprep(resp, p, msg, req); 00170 if (resp->seqno == 0) { 00171 if (req->seqno) { 00172 ast_log(LOG_DEBUG, " ************ Response seqno still zero!!!!!!!!!\n"); 00173 resp->seqno = req->seqno; 00174 } else { 00175 ast_log(LOG_DEBUG, " ************ Request seqno still zero!!!!!!!!! Can't set response seqno\n"); 00176 } 00177 } 00178 append_date(resp); 00179 switch (attach) { 00180 case WITH_DATE: 00181 add_header_contentLength(resp, 0); 00182 break; 00183 case WITH_MINEXPIRY: 00184 snprintf(buf, sizeof(buf), "%d", expiry.min_expiry); 00185 add_header(resp, "Min-Expires", buf); 00186 break; 00187 case WITH_ALLOW: 00188 add_header(resp, "Accept", "application/sdp"); 00189 add_header_contentLength(resp, 0); 00190 break; 00191 case WITH_SDP: 00192 if (p->rtp) { 00193 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 00194 if (option_debug) 00195 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 00196 ast_rtp_codec_setpref(p->rtp, &p->prefs); 00197 } 00198 try_suggested_sip_codec(p); 00199 add_sdp(resp, p); 00200 } else 00201 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 00202 break; 00203 case WITH_T38_SDP: 00204 if (p->udptl) { 00205 ast_udptl_offered_from_local(p->udptl, 0); 00206 add_t38_sdp(resp, p); 00207 } else 00208 ast_log(LOG_ERROR, "Can't add T38 SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 00209 break; 00210 } 00211 res = send_response(p, resp, reliable); 00212 if (reliable == XMIT_UNRELIABLE) 00213 siprequest_free(resp); 00214 return res; 00215 }
|
|
||||||||||||||||||||||||||||||||
|
Respond with authorization request.
Definition at line 236 of file sip3_transmit.c. References add_header(), add_header_contentLength(), ast_log(), get_header(), global, LOG_WARNING, sip_globals::realm, respprep(), send_response(), sip_request::seqno, SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00237 { 00238 struct sip_request *resp; 00239 char tmp[512]; 00240 int seqno = 0; 00241 int res; 00242 00243 00244 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 00245 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 00246 return -1; 00247 } 00248 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00249 00250 00251 /* Stale means that they sent us correct authentication, but 00252 based it on an old challenge (nonce) */ 00253 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global.realm, randdata, stale ? ", stale=true" : ""); 00254 respprep(resp, p, msg, req); 00255 add_header(resp, header, tmp); 00256 add_header_contentLength(resp, 0); 00257 res = send_response(p, resp, reliable); 00258 if (reliable == XMIT_UNRELIABLE) 00259 siprequest_free(resp); 00260 return res; 00261 }
|
|
||||||||||||||||||||
|
Transmit response, no retransmits.
Definition at line 218 of file sip3_transmit.c. References add_blank(), add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), SIP_MAX_PACKET, sipnet, siprequest_alloc(), siprequest_free(), and XMIT_UNRELIABLE. 00219 { 00220 struct sip_request *resp; 00221 int res; 00222 00223 resp = siprequest_alloc(SIP_MAX_PACKET, &sipnet); 00224 00225 respprep(resp, p, msg, req); 00226 append_date(resp); 00227 add_header(resp, "Unsupported", unsupported); 00228 add_header_contentLength(resp, 0); 00229 add_blank(resp); 00230 res = send_response(p, resp, XMIT_UNRELIABLE); 00231 siprequest_free(resp); 00232 return res; 00233 }
|
|
||||||||||||
|
Transmit SIP request unreliably (only used in sip_notify subsystem).
Definition at line 436 of file sip3_transmit.c. References initialize_initreq(), sip_dialog::initreq, send_request(), and XMIT_UNRELIABLE. 00437 { 00438 if (!p->initreq) /* Initialize first request before sending */ 00439 initialize_initreq(p, req); 00440 return send_request(p, req, XMIT_UNRELIABLE); 00441 }
|