Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:53 2007

Asterisk developer's documentation :: Codename Pineapple


sip3core.h File Reference

Go to the source code of this file.

Functions

const char * __get_header (const struct sip_request *req, const char *name, int *start)
void __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod, int reset)
int __sip_autodestruct (void *data)
void __sip_destroy (struct sip_pvt *p, int lockowner)
int __sip_do_register (struct sip_registry *r)
void __sip_pretend_ack (struct sip_pvt *p)
int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
int __sip_show_channels (int fd, int argc, char *argv[], int subscriptions)
int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
int _sip_show_peer (int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[])
int _sip_show_peers (int fd, int *total, struct mansession *s, struct message *m, int argc, char *argv[])
static void add_blank (struct sip_request *req)
 add a blank line if no body
void add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
int add_digit (struct sip_request *req, char digit)
int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
int add_header_contentLength (struct sip_request *req, int len)
 Add 'Content-Length' header to SIP message.
int add_line (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug)
sip_authadd_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno)
 Add realm authentication in list.
void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
int add_sdp (struct sip_request *resp, struct sip_pvt *p)
int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
int add_vidupdate (struct sip_request *req)
void append_date (struct sip_request *req)
 Append date to SIP message.
void append_history_full (struct sip_pvt *p, const char *fmt,...)
void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
int ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us)
int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
int auto_congest (void *nothing)
void build_callid_pvt (struct sip_pvt *pvt)
void build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
void build_contact (struct sip_pvt *p)
int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
void build_rpid (struct sip_pvt *p)
void build_via (struct sip_pvt *p)
int cb_extensionstate (char *context, char *exten, int state, void *data)
enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
void check_pendings (struct sip_pvt *p)
int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
void check_via (struct sip_pvt *p, struct sip_request *req)
void cleanup_stale_contexts (char *new, char *old)
int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
void clear_sip_domains (void)
 Clear our domain list (at reload).
char * complete_sip_debug_peer (const char *line, const char *word, int pos, int state)
char * complete_sip_peer (const char *word, int state, int flags2)
char * complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state)
char * complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state)
char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
char * complete_sip_user (const char *word, int state, int flags2)
char * complete_sipch (const char *line, const char *word, int pos, int state)
char * complete_sipnotify (const char *line, const char *word, int pos, int state)
int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
int create_addr (struct sip_pvt *dialog, const char *opeer)
int create_addr_from_peer (struct sip_pvt *r, struct sip_peer *peer)
void destroy_association (struct sip_peer *peer)
int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
void * do_monitor (void *data)
int does_peer_need_mwi (struct sip_peer *peer)
const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
const char * dtmfmode2str (int mode) attribute_const
int expire_register (void *data)
 Expire registration of SIP peer.
void extract_uri (struct sip_pvt *p, struct sip_request *req)
const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias Structure for conversion between compressed SIP and "normal" SIP.
sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime)
sip_authfind_realm_authentication (struct sip_auth *authlist, const char *realm)
 Find authentication for a specific realm.
int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
sip_peerfind_user (const char *name, int realtime)
void free_old_route (struct sip_route *route)
 Remove route from route list.
int func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
int func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
int function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
int function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
char * get_calleridname (const char *input, char *output, size_t outputsize)
 Get caller id name from SIP headers.
int get_destination (struct sip_pvt *p, struct sip_request *oreq)
const char * get_header (const struct sip_request *req, const char *name)
char * get_in_brackets (char *tmp)
 Pick out text in brackets from character string.
int get_msg_text (char *buf, int len, struct sip_request *req)
int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
int get_rpid_num (const char *input, char *output, int maxlen)
 Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin)
int handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
void handle_request_info (struct sip_pvt *p, struct sip_request *req)
int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e)
int handle_request_message (struct sip_pvt *p, struct sip_request *req)
int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
int handle_request_options (struct sip_pvt *p, struct sip_request *req)
int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock)
int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
int handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
void handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
const char * insecure2str (int port, int invite) attribute_const
void list_route (struct sip_route *route)
int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
int manager_sip_show_peer (struct mansession *s, struct message *m)
int manager_sip_show_peers (struct mansession *s, struct message *m)
int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
char * nat2str (int nat) attribute_const
void parse_copy (struct sip_request *dst, const struct sip_request *src)
void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
void parse_request (struct sip_request *req)
 Parse a SIP message.
unsigned int parse_sip_options (struct sip_pvt *pvt, const char *supported)
int peer_status (struct sip_peer *peer, char *status, int statuslen)
void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
void receive_message (struct sip_pvt *p, struct sip_request *req)
void reg_source_db (struct sip_peer *peer)
void register_peer_exten (struct sip_peer *peer, int onoff)
enum check_auth_result register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
char * regstate2str (enum sipregistrystate regstate) attribute_const
 Convert registration state status to string.
int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
int restart_monitor (void)
 Start the channel monitor thread.
int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
int set_address_from_contact (struct sip_pvt *pvt)
void set_destination (struct sip_pvt *p, char *uri)
void set_device_defaults (struct sip_peer *peer)
int sip_addheader (struct ast_channel *chan, void *data)
int sip_addrcmp (char *name, struct sockaddr_in *sin)
sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method)
 Allocate SIP_PVT structure and set defaults.
void sip_cancel_destroy (struct sip_pvt *p)
int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
int sip_debug_test_pvt (struct sip_pvt *p)
void sip_destroy (struct sip_pvt *p)
void sip_destroy_device (struct sip_peer *peer)
int sip_devicestate (void *data)
int sip_do_debug (int fd, int argc, char *argv[])
int sip_do_debug_ip (int fd, int argc, char *argv[])
int sip_do_debug_peer (int fd, int argc, char *argv[])
int sip_do_history (int fd, int argc, char *argv[])
int sip_do_reload (enum channelreloadreason reason)
int sip_dtmfmode (struct ast_channel *chan, void *data)
void sip_dump_history (struct sip_pvt *dialog)
int sip_get_codec (struct ast_channel *chan)
ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
int sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite)
const char * sip_nat_mode (const struct sip_pvt *p)
int sip_no_debug (int fd, int argc, char *argv[])
int sip_no_history (int fd, int argc, char *argv[])
int sip_notify (int fd, int argc, char *argv[])
int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
void * sip_park_thread (void *stuff)
void sip_peer_hold (struct sip_pvt *p, int hold)
void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
int sip_poke_noanswer (void *data)
 React to lack of answer to Qualify poke.
int sip_poke_peer (struct sip_peer *peer)
int sip_poke_peer_s (void *data)
 Poke peer (send qualify to check if peer is alive and well).
int sip_prune_realtime (int fd, int argc, char *argv[])
 Remove temporary realtime objects from memory (CLI).
const struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
int sip_refer_allocate (struct sip_pvt *p)
int sip_reg_timeout (void *data)
int sip_register (char *value, int lineno)
void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
int sip_reload (int fd, int argc, char *argv[])
int sip_reregister (void *data)
ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
void sip_scheddestroy (struct sip_pvt *p, int ms)
void sip_send_all_registers (void)
 Send all known registrations.
int sip_send_mwi_to_peer (struct sip_peer *peer)
int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 Set the RTP peer for this call.
int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
int sip_show_channel (int fd, int argc, char *argv[])
int sip_show_channels (int fd, int argc, char *argv[])
int sip_show_domains (int fd, int argc, char *argv[])
 CLI command to list local domains.
int sip_show_history (int fd, int argc, char *argv[])
int sip_show_inuse (int fd, int argc, char *argv[])
int sip_show_objects (int fd, int argc, char *argv[])
int sip_show_peer (int fd, int argc, char *argv[])
int sip_show_peers (int fd, int argc, char *argv[])
int sip_show_registry (int fd, int argc, char *argv[])
int sip_show_settings (int fd, int argc, char *argv[])
int sip_show_subscriptions (int fd, int argc, char *argv[])
int sip_show_user (int fd, int argc, char *argv[])
int sip_show_users (int fd, int argc, char *argv[])
int sip_sipredirect (struct sip_pvt *p, const char *dest)
sip_peertemp_peer (const char *name)
char * transfermode2str (enum transfermodes mode) attribute_const
void transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable)
int transmit_info_with_digit (struct sip_pvt *p, const char digit)
int transmit_info_with_vidupdate (struct sip_pvt *p)
int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
int transmit_message_with_text (struct sip_pvt *p, const char *text)
int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
int transmit_refer (struct sip_pvt *p, const char *dest)
int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA.
int transmit_reinvite_with_sdp (struct sip_pvt *p)
int transmit_reinvite_with_t38_sdp (struct sip_pvt *p)
int transmit_request (struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch)
int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale)
int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
int transmit_sip_request (struct sip_pvt *p, struct sip_request *req)
int transmit_state_notify (struct sip_pvt *p, int state, int full)
void try_suggested_sip_codec (struct sip_pvt *p)
int update_call_counter (struct sip_pvt *fup, int event)
void update_peer (struct sip_peer *p, int expiry)


Function Documentation

const char* __get_header const struct sip_request req,
const char *  name,
int *  start
 

void __sip_ack struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod,
int  reset
 

int __sip_autodestruct void *  data  ) 
 

void __sip_destroy struct sip_pvt p,
int  lockowner
 

int __sip_do_register struct sip_registry r  ) 
 

void __sip_pretend_ack struct sip_pvt p  ) 
 

int __sip_semi_ack struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod
 

int __sip_show_channels int  fd,
int  argc,
char *  argv[],
int  subscriptions
 

int __transmit_response struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable
 

int _sip_show_peer int  type,
int  fd,
struct mansession s,
struct message m,
int  argc,
char *  argv[]
 

int _sip_show_peers int  fd,
int *  total,
struct mansession s,
struct message m,
int  argc,
char *  argv[]
 

static void add_blank struct sip_request req  )  [static]
 

add a blank line if no body

Definition at line 128 of file sip3_compose.c.

00129 {
00130    if (!req->lines) {
00131       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
00132       snprintf(req->data + req->len, req->data_size - req->len, "\r\n");
00133       req->len += strlen(req->data + req->len);
00134    }
00135 }

void add_codec_to_sdp const struct sip_pvt p,
int  codec,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
 

int add_digit struct sip_request req,
char  digit
 

int add_header struct sip_request req,
const char *  var,
const char *  value
 

Add header to SIP message.

Definition at line 89 of file sip3_compose.c.

00090 {
00091    int maxlen = req->data_size - 4 - req->len; /* 4 bytes are for two \r\n ? */
00092 
00093    if (req->headers == SIP_MAX_HEADERS) {
00094       ast_log(LOG_WARNING, "Out of SIP header space\n");
00095       return -1;
00096    }
00097 
00098    if (req->lines) {
00099       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
00100       return -1;
00101    }
00102 
00103    if (maxlen <= 0) {
00104       ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value);
00105       if (option_debug > 2)
00106          ast_log(LOG_DEBUG, "    ==== Req->len %d, req->data size %d Maxlen %d\n", req->len, (int) req->data_size, maxlen);
00107       return -1;
00108    }
00109 
00110    req->header[req->headers] = req->data + req->len;
00111 
00112    if (global.compactheaders)
00113       var = find_alias(var, var);
00114 
00115    snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value);
00116    req->len += strlen(req->header[req->headers]);
00117    req->headers++;
00118    if (req->headers < SIP_MAX_HEADERS)
00119       req->headers++;
00120    else
00121       ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n");
00122 
00123    return 0;   
00124 }

int add_header_contentLength struct sip_request req,
int  len
 

Add 'Content-Length' header to SIP message.

Definition at line 362 of file sip3_compose.c.

00363 {
00364    char clen[10];
00365 
00366    snprintf(clen, sizeof(clen), "%d", len);
00367    return add_header(req, "Content-Length", clen);
00368 }

int add_line struct sip_request req,
const char *  line
 

Add content (not header) to SIP message.

Definition at line 399 of file sip3_compose.c.

00400 {
00401    if (req->lines == SIP_MAX_LINES)  {
00402       ast_log(LOG_WARNING, "Out of SIP line space\n");
00403       return -1;
00404    }
00405    if (!req->lines) {
00406       /* Add extra empty return */
00407       snprintf(req->data + req->len, req->data_size - req->len, "\r\n");
00408       req->len += strlen(req->data + req->len);
00409    }
00410    if (req->len >= req->data_size - 4) {
00411       ast_log(LOG_WARNING, "Out of space, can't add anymore: Len %d Data %dd\n", req->len, (int) req->data_size);
00412       return -1;
00413    }
00414    req->line[req->lines] = req->data + req->len;
00415    snprintf(req->line[req->lines], req->data_size - req->len, "%s", line);
00416    req->len += strlen(req->line[req->lines]);
00417    req->lines++;
00418    return 0;   
00419 }

void add_noncodec_to_sdp const struct sip_pvt p,
int  format,
int  sample_rate,
char **  m_buf,
size_t *  m_size,
char **  a_buf,
size_t *  a_size,
int  debug
 

struct sip_auth* add_realm_authentication struct sip_auth authlist,
char *  configuration,
int  lineno
 

Add realm authentication in list.

Definition at line 495 of file sip3_auth.c.

00496 {
00497    char authcopy[256];
00498    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
00499    char *stringp;
00500    struct sip_auth *a, *b, *auth;
00501 
00502    if (ast_strlen_zero(configuration))
00503       return authlist;
00504 
00505    if (option_debug)
00506       ast_log(LOG_DEBUG, "Auth config ::  %s\n", configuration);
00507 
00508    ast_copy_string(authcopy, configuration, sizeof(authcopy));
00509    stringp = authcopy;
00510 
00511    username = stringp;
00512    realm = strrchr(stringp, '@');
00513    if (realm)
00514       *realm++ = '\0';
00515    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
00516       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
00517       return authlist;
00518    }
00519    stringp = username;
00520    username = strsep(&stringp, ":");
00521    if (username) {
00522       secret = strsep(&stringp, ":");
00523       if (!secret) {
00524          stringp = username;
00525          md5secret = strsep(&stringp,"#");
00526       }
00527    }
00528    if (!(auth = ast_calloc(1, sizeof(*auth))))
00529       return authlist;
00530 
00531    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
00532    ast_copy_string(auth->username, username, sizeof(auth->username));
00533    if (secret)
00534       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
00535    if (md5secret)
00536       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
00537 
00538    /* find the end of the list */
00539    for (b = NULL, a = authlist; a ; b = a, a = a->next)
00540       ;
00541    if (b)
00542       b->next = auth;   /* Add structure add end of list */
00543    else
00544       authlist = auth;
00545 
00546    if (option_verbose > 2)
00547       ast_verbose("Added authentication for realm %s\n", realm);
00548 
00549    return authlist;
00550 
00551 }

void add_route struct sip_request req,
struct sip_route route
 

Add route header into request per learned route.

Definition at line 371 of file sip3_compose.c.

00372 {
00373    char r[BUFSIZ*2], *p;
00374    int n, rem = sizeof(r);
00375 
00376    if (!route)
00377       return;
00378 
00379    p = r;
00380    for (;route ; route = route->next) {
00381       n = strlen(route->hop);
00382       if (rem < n+3) /* we need room for ",<route>" */
00383          break;
00384       if (p != r) {  /* add a separator after fist route */
00385          *p++ = ',';
00386          --rem;
00387       }
00388       *p++ = '<';
00389       ast_copy_string(p, route->hop, rem); /* cannot fail */
00390       p += n;
00391       *p++ = '>';
00392       rem -= (n+2);
00393    }
00394    *p = '\0';
00395    add_header(req, "Route", r);
00396 }

int add_sdp struct sip_request resp,
struct sip_pvt p
 

int add_sip_domain const char *  domain,
const enum domain_mode  mode,
const char *  context
 

Add SIP domain to list of domains we are responsible for.

Definition at line 95 of file sip3_domain.c.

00096 {
00097    struct domain *d;
00098 
00099    if (ast_strlen_zero(domain)) {
00100       ast_log(LOG_WARNING, "Zero length domain.\n");
00101       return 1;
00102    }
00103 
00104    if (!(d = ast_calloc(1, sizeof(*d))))
00105       return 0;
00106 
00107    ast_copy_string(d->domain, domain, sizeof(d->domain));
00108 
00109    if (!ast_strlen_zero(context))
00110       ast_copy_string(d->context, context, sizeof(d->context));
00111 
00112    d->mode = mode;
00113 
00114    AST_LIST_LOCK(&domain_list);
00115    AST_LIST_INSERT_TAIL(&domain_list, d, list);
00116    AST_LIST_UNLOCK(&domain_list);
00117 
00118    if (option_debug > 2)   
00119       ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
00120 
00121    return 1;
00122 }

int add_text struct sip_request req,
const char *  text
 

Add text body to SIP message.

Definition at line 195 of file sip3_compose.c.

00196 {
00197    /* XXX Convert \n's to \r\n's XXX */
00198    add_header(req, "Content-Type", "text/plain");
00199    add_header_contentLength(req, strlen(text));
00200    add_line(req, text);
00201    return 0;
00202 }

int add_vidupdate struct sip_request req  ) 
 

void append_date struct sip_request req  ) 
 

Append date to SIP message.

Definition at line 175 of file sip3_compose.c.

00176 {
00177    char tmpdat[256];
00178    struct tm tm;
00179    time_t t = time(NULL);
00180 
00181    gmtime_r(&t, &tm);
00182    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
00183    add_header(req, "Date", tmpdat);
00184 }

void append_history_full struct sip_pvt p,
const char *  fmt,
  ...
 

void ast_quiet_chan struct ast_channel chan  ) 
 

Turn off generator data XXX Does this function belong in the SIP channel?

Definition at line 4034 of file chan_sip3.c.

04035 {
04036    if (chan && chan->_state == AST_STATE_UP) {
04037       if (chan->generatordata)
04038          ast_deactivate_generator(chan);
04039    }
04040 }

int ast_sip_ouraddrfor struct in_addr *  them,
struct in_addr *  us
 

int attempt_transfer struct sip_dual transferer,
struct sip_dual target
 

int auto_congest void *  nothing  ) 
 

void build_callid_pvt struct sip_pvt pvt  ) 
 

void build_callid_registry struct sip_registry reg,
struct in_addr  ourip,
const char *  fromdomain
 

void build_contact struct sip_pvt p  ) 
 

int build_reply_digest struct sip_pvt p,
int  method,
char *  digest,
int  digest_len
 

void build_route struct sip_pvt p,
struct sip_request req,
int  backwards
 

void build_rpid struct sip_pvt p  ) 
 

void build_via struct sip_pvt p  ) 
 

int cb_extensionstate char *  context,
char *  exten,
int  state,
void *  data
 

enum check_auth_result check_auth struct sip_pvt p,
struct sip_request req,
const char *  username,
const char *  secret,
const char *  md5secret,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
int  ignore
 

void check_pendings struct sip_pvt p  ) 
 

int check_sip_domain const char *  domain,
char *  context,
size_t  len
 

check_sip_domain: Check if domain part of uri is local to our server

Definition at line 132 of file sip3_domain.c.

00133 {
00134    struct domain *d;
00135    int result = 0;
00136 
00137    AST_LIST_LOCK(&domain_list);
00138    AST_LIST_TRAVERSE(&domain_list, d, list) {
00139       if (strcasecmp(d->domain, domain))
00140          continue;
00141 
00142       if (len && !ast_strlen_zero(d->context))
00143          ast_copy_string(context, d->context, len);
00144       
00145       result = 1;
00146       break;
00147    }
00148    AST_LIST_UNLOCK(&domain_list);
00149 
00150    return result;
00151 }

int check_user struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin
 

enum check_auth_result check_user_full struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin,
struct sip_peer **  authpeer
 

void check_via struct sip_pvt p,
struct sip_request req
 

void cleanup_stale_contexts char *  new,
char *  old
 

int clear_realm_authentication struct sip_auth authlist  ) 
 

Clear realm authentication list (at reload).

Definition at line 554 of file sip3_auth.c.

00555 {
00556    struct sip_auth *a = authlist;
00557    struct sip_auth *b;
00558 
00559    while (a) {
00560       b = a;
00561       a = a->next;
00562       free(b);
00563    }
00564 
00565    return 1;
00566 }

void clear_sip_domains void   ) 
 

Clear our domain list (at reload).

Definition at line 154 of file sip3_domain.c.

00155 {
00156    struct domain *d;
00157 
00158    AST_LIST_LOCK(&domain_list);
00159    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
00160       free(d);
00161    AST_LIST_UNLOCK(&domain_list);
00162 }

char* complete_sip_debug_peer const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sip_peer const char *  word,
int  state,
int  flags2
 

char* complete_sip_prune_realtime_peer const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sip_prune_realtime_user const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sip_show_peer const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sip_show_user const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sip_user const char *  word,
int  state,
int  flags2
 

char* complete_sipch const char *  line,
const char *  word,
int  pos,
int  state
 

char* complete_sipnotify const char *  line,
const char *  word,
int  pos,
int  state
 

int copy_all_header struct sip_request req,
const struct sip_request orig,
const char *  field
 

int copy_header struct sip_request req,
const struct sip_request orig,
const char *  field
 

void copy_request struct sip_request dst,
const struct sip_request src
 

copy SIP request (mostly used to save request for responses)

Definition at line 238 of file sip3_parse.c.

00239 {
00240    long offset;
00241    int x;
00242 
00243    offset = ((void *)dst) - ((void *)src);
00244    /* First copy stuff */
00245    memcpy(dst, src, sizeof(*dst));
00246    
00247    /* Now, fix data part */
00248    if (dst->data)
00249       free(dst->data);
00250    dst->data = ast_calloc(1, src->data_size);
00251    dst->data_size = src->data_size;
00252    memcpy(dst->data, src->data, src->data_size);
00253 
00254    /* Now fix pointer arithmetic */
00255    for (x=0; x < src->headers; x++)
00256       dst->header[x] += offset;
00257    for (x=0; x < src->lines; x++)
00258       dst->line[x] += offset;
00259 
00260    if (option_debug > 3)
00261       ast_log(LOG_DEBUG, "==== Copied request... \n");
00262 }

int copy_via_headers struct sip_pvt p,
struct sip_request req,
const struct sip_request orig,
const char *  field
 

int create_addr struct sip_pvt dialog,
const char *  opeer
 

int create_addr_from_peer struct sip_pvt r,
struct sip_peer peer
 

void destroy_association struct sip_peer peer  ) 
 

int determine_firstline_parts struct sip_request req  ) 
 

Parse first line of incoming SIP request.

Definition at line 865 of file sip3_parse.c.

00866 {
00867    char *e = ast_skip_blanks(req->header[0]);   /* there shouldn't be any */
00868 
00869    if (!*e)
00870       return -1;
00871    req->rlPart1 = e; /* method or protocol */
00872    e = ast_skip_nonblanks(e);
00873    if (*e)
00874       *e++ = '\0';
00875    /* Get URI or status code */
00876    e = ast_skip_blanks(e);
00877    if ( !*e )
00878       return -1;
00879    ast_trim_blanks(e);
00880 
00881    if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */
00882       if (strlen(e) < 3)   /* status code is 3 digits */
00883          return -1;
00884       req->rlPart2 = e;
00885    } else { /* We have a request */
00886       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
00887          ast_log(LOG_WARNING, "bogus uri in <> %s\n", e);
00888          e++;
00889          if (!*e)
00890             return -1; 
00891       }
00892       req->rlPart2 = e; /* URI */
00893       e = ast_skip_nonblanks(e);
00894       if (*e)
00895          *e++ = '\0';
00896       e = ast_skip_blanks(e);
00897       if (strcasecmp(e, "SIP/2.0") ) {
00898          ast_log(LOG_WARNING, "Bad request protocol %s\n", e);
00899          return -1;
00900       }
00901    }
00902    return 1;
00903 }

void* do_monitor void *  data  ) 
 

int does_peer_need_mwi struct sip_peer peer  ) 
 

const char* domain_mode_to_text const enum domain_mode  mode  ) 
 

Print domain mode to cli.

Definition at line 191 of file sip3_domain.c.

00192 {
00193    switch (mode) {
00194    case SIP_DOMAIN_AUTO:
00195       return "[Automatic]";
00196    case SIP_DOMAIN_CONFIG:
00197       return "[Configured]";
00198    }
00199 
00200    return "";
00201 }

const char* dtmfmode2str int  mode  )  const
 

int expire_register void *  data  ) 
 

Expire registration of SIP peer.

Definition at line 391 of file sip3_objects.c.

00392 {
00393    struct sip_device *device = data;
00394    
00395    if (!device)      /* Hmmm. We have no peer. Weird. */
00396       return 0;
00397 
00398    memset(&device->addr, 0, sizeof(device->addr));
00399 
00400    destroy_association(device);  /* remove registration data from storage */
00401    
00402    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", device->name);
00403    register_peer_exten(device, FALSE); /* Remove regexten */
00404    device->expire = -1;
00405    ast_device_state_changed("SIP/%s", device->name);
00406 
00407    /* Do we need to release this peer from memory? 
00408       Only for realtime peers and autocreated peers
00409    */
00410    if (ast_test_flag(&device->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
00411        ast_test_flag(&device->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
00412       device = ASTOBJ_CONTAINER_UNLINK(&devicelist, device);   /* Remove from peer list */
00413       device_unref(device);
00414    }
00415 
00416    return 0;
00417 }

void extract_uri struct sip_pvt p,
struct sip_request req
 

const char* find_alias const char *  name,
const char *  _default
 

Find compressed SIP alias Structure for conversion between compressed SIP and "normal" SIP.

Definition at line 320 of file sip3_parse.c.

00321 {
00322    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
00323    static const struct cfalias {
00324       char * const fullname;
00325       char * const shortname;
00326    } aliases[] = {
00327       { "Content-Type",  "c" },
00328       { "Content-Encoding",    "e" },
00329       { "From",       "f" },
00330       { "Call-ID",       "i" },
00331       { "Contact",       "m" },
00332       { "Content-Length",   "l" },
00333       { "Subject",       "s" },
00334       { "To",         "t" },
00335       { "Supported",     "k" },
00336       { "Refer-To",      "r" },
00337       { "Referred-By",   "b" },
00338       { "Allow-Events",  "u" },
00339       { "Event",      "o" },
00340       { "Via",     "v" },
00341       { "Accept-Contact",      "a" },
00342       { "Reject-Contact",      "j" },
00343       { "Request-Disposition", "d" },
00344       { "Session-Expires",     "x" },
00345       { "Identity",            "y" },
00346       { "Identity-Info",       "n" },
00347    };
00348    int x;
00349 
00350    for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
00351       if (!strcasecmp(aliases[x].fullname, name))
00352          return aliases[x].shortname;
00353 
00354    return _default;
00355 }

struct sip_pvt* find_call struct sip_request req,
struct sockaddr_in *  sin,
const int  intended_method
 

struct sip_peer* find_peer const char *  peer,
struct sockaddr_in *  sin,
int  realtime
 

struct sip_auth* find_realm_authentication struct sip_auth authlist,
const char *  realm
 

Find authentication for a specific realm.

Definition at line 569 of file sip3_auth.c.

00570 {
00571    struct sip_auth *a;
00572 
00573    for (a = authlist; a; a = a->next) {
00574       if (!strcasecmp(a->realm, realm))
00575          break;
00576    }
00577 
00578    return a;
00579 }

int find_sdp struct sip_request req  ) 
 

Determine whether a SIP message contains an SDP in its body.

Parameters:
req the SIP request to process
Returns:
TRUE if SDP found, FALSE if not found
Also updates req->sdp_start and req->sdp_end to indicate where the SDP lives in the message body.

Definition at line 880 of file sip3_sdprtp.c.

00881 {
00882    const char *content_type;
00883    const char *search;
00884    char *boundary;
00885    unsigned int x;
00886 
00887    content_type = get_header(req, "Content-Type");
00888 
00889    /* if the body contains only SDP, this is easy */
00890    if (!strcasecmp(content_type, "application/sdp")) {
00891       req->sdp_start = 0;
00892       req->sdp_end = req->lines;
00893       return TRUE;
00894    }
00895 
00896    /* if it's not multipart/mixed, there cannot be an SDP */
00897    if (strncasecmp(content_type, "multipart/mixed", 15))
00898       return FALSE;
00899 
00900    /* if there is no boundary marker, it's invalid */
00901    if (!(search = strcasestr(content_type, ";boundary=")))
00902       return FALSE;
00903 
00904    search += 10;
00905 
00906    if (ast_strlen_zero(search))
00907       return FALSE;
00908 
00909    /* make a duplicate of the string, with two extra characters
00910       at the beginning */
00911    boundary = ast_strdupa(search - 2);
00912    boundary[0] = boundary[1] = '-';
00913 
00914    /* search for the boundary marker, but stop when there are not enough
00915       lines left for it, the Content-Type header and at least one line of
00916       body */
00917    for (x = 0; x < (req->lines - 2); x++) {
00918       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
00919           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
00920          x += 2;
00921          req->sdp_start = x;
00922          /* search for the end of the body part */
00923          for ( ; x < req->lines; x++) {
00924             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
00925                break;
00926          }
00927          req->sdp_end = x;
00928          return TRUE;
00929       }
00930    }
00931 
00932    return FALSE;
00933 }

int find_sip_method const char *  msg  ) 
 

find_sip_method: Find SIP method from header

Definition at line 163 of file sip3_parse.c.

00164 {
00165    int i, res = 0;
00166    
00167    if (ast_strlen_zero(msg))
00168       return 0;
00169    for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) {
00170       if (method_match(i, msg))
00171          res = sip_methods[i].id;
00172    }
00173    return res;
00174 }

struct sip_peer* find_user const char *  name,
int  realtime
 

void free_old_route struct sip_route route  ) 
 

Remove route from route list.

Definition at line 2084 of file chan_sip3.c.

02085 {
02086    struct sip_route *next;
02087 
02088    while (route) {
02089       next = route->next;
02090       free(route);
02091       route = next;
02092    }
02093 }

int func_check_sipdomain struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
 

Dial plan function to check if domain is local.

Definition at line 166 of file sip3_domain.c.

00167 {
00168    if (ast_strlen_zero(data)) {
00169       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
00170       return -1;
00171    }
00172    if (check_sip_domain(data, NULL, 0))
00173       ast_copy_string(buf, data, len);
00174    else
00175       buf[0] = '\0';
00176    return 0;
00177 }

int func_header_read struct ast_channel chan,
char *  function,
char *  data,
char *  buf,
size_t  len
 

int function_sipchaninfo_read struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
 

int function_sippeer struct ast_channel chan,
char *  cmd,
char *  data,
char *  buf,
size_t  len
 

char* generate_random_string char *  buf,
size_t  size
 

Generate 32 byte random string for callid's etc.

Definition at line 852 of file sip3_parse.c.

00853 {
00854    long val[4];
00855    int x;
00856 
00857    for (x=0; x<4; x++)
00858       val[x] = ast_random();
00859    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
00860 
00861    return buf;
00862 }

int get_also_info struct sip_pvt p,
struct sip_request oreq
 

char* get_calleridname const char *  input,
char *  output,
size_t  outputsize
 

Get caller id name from SIP headers.

Definition at line 130 of file sip3_callerid.c.

00131 {
00132    const char *end = strchr(input,'<');   /* first_bracket */
00133    const char *tmp = strchr(input,'"');   /* first quote */
00134    int bytes = 0;
00135    int maxbytes = outputsize - 1;
00136 
00137    if (!end || end == input)  /* we require a part in brackets */
00138       return NULL;
00139 
00140    /* move away from "<" */
00141    end--;
00142 
00143    /* we found "name" */
00144    if (tmp && tmp < end) {
00145       end = strchr(tmp+1, '"');
00146       if (!end)
00147          return NULL;
00148       bytes = (int) (end - tmp);
00149       /* protect the output buffer */
00150       if (bytes > maxbytes)
00151          bytes = maxbytes;
00152       ast_copy_string(output, tmp + 1, bytes);
00153    } else {
00154       /* we didn't find "name" */
00155       /* clear the empty characters in the begining*/
00156       input = ast_skip_blanks(input);
00157       /* clear the empty characters in the end */
00158       while(*end && *end < 33 && end > input)
00159          end--;
00160       if (end >= input) {
00161          bytes = (int) (end - input) + 2;
00162          /* protect the output buffer */
00163          if (bytes > maxbytes)
00164             bytes = maxbytes;
00165          ast_copy_string(output, input, bytes);
00166       } else
00167          return NULL;
00168    }
00169    return output;
00170 }

int get_destination struct sip_pvt p,
struct sip_request oreq
 

const char * get_header const struct sip_request req,
const char *  name
 

char* get_in_brackets char *  tmp  ) 
 

Pick out text in brackets from character string.

Returns:
pointer to terminated stripped string
Parameters:
tmp input string that will be modified Examples:
"foo" <bar> valid input, returns bar foo returns the whole string < "foo ... > returns the string between brackets < "foo... bogus (missing closing bracket), returns the whole string XXX maybe should still skip the opening bracket

Definition at line 771 of file sip3_parse.c.

00772 {
00773    const char *parse = tmp;
00774    char *first_bracket;
00775 
00776    /*
00777     * Skip any quoted text until we find the part in brackets.
00778          * On any error give up and return the full string.
00779          */
00780         while ( (first_bracket = strchr(parse, '<')) ) {
00781                 char *first_quote = strchr(parse, '"');
00782 
00783       if (!first_quote || first_quote > first_bracket)
00784          break; /* no need to look at quoted part */
00785       /* the bracket is within quotes, so ignore it */
00786       parse = find_closing_quote(first_quote + 1, NULL);
00787       if (!*parse) { /* not found, return full string ? */
00788          /* XXX or be robust and return in-bracket part ? */
00789          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
00790          break;
00791       }
00792       parse++;
00793    }
00794    if (first_bracket) {
00795       char *second_bracket = strchr(first_bracket + 1, '>');
00796       if (second_bracket) {
00797          *second_bracket = '\0';
00798          tmp = first_bracket + 1;
00799       } else {
00800          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
00801       }
00802    }
00803    return tmp;
00804 }

int get_msg_text char *  buf,
int  len,
struct sip_request req
 

int get_rdnis struct sip_pvt p,
struct sip_request oreq
 

int get_refer_info struct sip_pvt transferer,
struct sip_request outgoing_req
 

int get_rpid_num const char *  input,
char *  output,
int  maxlen
 

Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.

Definition at line 102 of file sip3_callerid.c.

00103 {
00104    char *start;
00105    char *end;
00106 
00107    start = strchr(input,':');
00108    if (!start) {
00109       output[0] = '\0';
00110       return 0;
00111    }
00112    start++;
00113 
00114    /* we found "number" */
00115    ast_copy_string(output,start,maxlen);
00116    output[maxlen-1] = '\0';
00117 
00118    end = strchr(output,'@');
00119    if (end)
00120       *end = '\0';
00121    else
00122       output[0] = '\0';
00123    if (strstr(input,"privacy=full") || strstr(input,"privacy=uri"))
00124       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
00125 
00126    return 0;
00127 }

struct sip_pvt* get_sip_pvt_byid_locked const char *  callid,
const char *  totag,
const char *  fromtag
 

const char * gettag const struct sip_request req,
const char *  header,
char *  tagbuf,
int  tagbufsize
 

int handle_common_options struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v
 

int handle_invite_replaces struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
int  seqno,
struct sockaddr_in *  sin
 

int handle_request struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int *  recount,
int *  nounlock
 

int handle_request_bye struct sip_pvt p,
struct sip_request req
 

int handle_request_cancel struct sip_pvt p,
struct sip_request req
 

void handle_request_info struct sip_pvt p,
struct sip_request req
 

int handle_request_invite struct sip_pvt p,
struct sip_request req,
int  debug,
int  seqno,
struct sockaddr_in *  sin,
int *  recount,
char *  e
 

int handle_request_message struct sip_pvt p,
struct sip_request req
 

int handle_request_notify struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int  seqno,
char *  e
 

int handle_request_options struct sip_pvt p,
struct sip_request req
 

int handle_request_refer struct sip_pvt p,
struct sip_request req,
int  debug,
int  ignore,
int  seqno,
int *  nounlock
 

int handle_request_register struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
char *  e
 

int handle_request_subscribe struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int  seqno,
char *  e
 

void handle_response struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno
 

void handle_response_invite struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno
 

int handle_response_peerpoke struct sip_pvt p,
int  resp,
struct sip_request req
 

void handle_response_refer struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno
 

int handle_response_register struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno
 

const char* hangup_cause2sip int  cause  ) 
 

Convert Asterisk hangup causes to SIP codes.

 Possible values from causes.h
        AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
        AST_CAUSE_FAILURE       AST_CAUSE_CONGESTION    AST_CAUSE_UNALLOCATED

	In addition to these, a lot of PRI codes is defined in causes.h 
	...should we take care of them too ?
	
	Quote RFC 3398

   ISUP Cause value                        SIP response
   ----------------                        ------------
   1  unallocated number                   404 Not Found
   2  no route to network                  404 Not found
   3  no route to destination              404 Not found
   16 normal call clearing                 --- (*)
   17 user busy                            486 Busy here
   18 no user responding                   408 Request Timeout
   19 no answer from the user              480 Temporarily unavailable
   20 subscriber absent                    480 Temporarily unavailable
   21 call rejected                        403 Forbidden (+)
   22 number changed (w/o diagnostic)      410 Gone
   22 number changed (w/ diagnostic)       301 Moved Permanently
   23 redirection to new destination       410 Gone
   26 non-selected user clearing           404 Not Found (=)
   27 destination out of order             502 Bad Gateway
   28 address incomplete                   484 Address incomplete
   29 facility rejected                    501 Not implemented
   31 normal unspecified                   480 Temporarily unavailable

Definition at line 681 of file sip3_dialog.c.

00682 {
00683    switch (cause) {
00684       case AST_CAUSE_UNALLOCATED:      /* 1 */
00685       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
00686       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
00687          return "404 Not Found";
00688       case AST_CAUSE_CONGESTION:    /* 34 */
00689       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
00690          return "503 Service Unavailable";
00691       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
00692          return "408 Request Timeout";
00693       case AST_CAUSE_NO_ANSWER:     /* 19 */
00694          return "480 Temporarily unavailable";
00695       case AST_CAUSE_CALL_REJECTED:    /* 21 */
00696          return "403 Forbidden";
00697       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
00698          return "410 Gone";
00699       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
00700          return "480 Temporarily unavailable";
00701       case AST_CAUSE_INVALID_NUMBER_FORMAT:
00702          return "484 Address incomplete";
00703       case AST_CAUSE_USER_BUSY:
00704          return "486 Busy here";
00705       case AST_CAUSE_FAILURE:
00706          return "500 Server internal failure";
00707       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
00708          return "501 Not Implemented";
00709       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
00710          return "503 Service Unavailable";
00711       /* Used in chan_iax2 */
00712       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
00713          return "502 Bad Gateway";
00714       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
00715          return "488 Not Acceptable Here";
00716          
00717       case AST_CAUSE_NOTDEFINED:
00718       default:
00719          if (option_debug)
00720             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
00721          return NULL;
00722    }
00723 
00724    /* Never reached */
00725    return 0;
00726 }

int hangup_sip2cause int  cause  ) 
 

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 567 of file sip3_dialog.c.

00568 {
00569    /* Possible values taken from causes.h */
00570 
00571    switch(cause) {
00572       case 401:   /* Unauthorized */
00573          return AST_CAUSE_CALL_REJECTED;
00574       case 403:   /* Not found */
00575          return AST_CAUSE_CALL_REJECTED;
00576       case 404:   /* Not found */
00577          return AST_CAUSE_UNALLOCATED;
00578       case 405:   /* Method not allowed */
00579          return AST_CAUSE_INTERWORKING;
00580       case 407:   /* Proxy authentication required */
00581          return AST_CAUSE_CALL_REJECTED;
00582       case 408:   /* No reaction */
00583          return AST_CAUSE_NO_USER_RESPONSE;
00584       case 409:   /* Conflict */
00585          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
00586       case 410:   /* Gone */
00587          return AST_CAUSE_UNALLOCATED;
00588       case 411:   /* Length required */
00589          return AST_CAUSE_INTERWORKING;
00590       case 413:   /* Request entity too large */
00591          return AST_CAUSE_INTERWORKING;
00592       case 414:   /* Request URI too large */
00593          return AST_CAUSE_INTERWORKING;
00594       case 415:   /* Unsupported media type */
00595          return AST_CAUSE_INTERWORKING;
00596       case 420:   /* Bad extension */
00597          return AST_CAUSE_NO_ROUTE_DESTINATION;
00598       case 480:   /* No answer */
00599          return AST_CAUSE_NO_ANSWER;
00600       case 481:   /* No answer */
00601          return AST_CAUSE_INTERWORKING;
00602       case 482:   /* Loop detected */
00603          return AST_CAUSE_INTERWORKING;
00604       case 483:   /* Too many hops */
00605          return AST_CAUSE_NO_ANSWER;
00606       case 484:   /* Address incomplete */
00607          return AST_CAUSE_INVALID_NUMBER_FORMAT;
00608       case 485:   /* Ambigous */
00609          return AST_CAUSE_UNALLOCATED;
00610       case 486:   /* Busy everywhere */
00611          return AST_CAUSE_BUSY;
00612       case 487:   /* Request terminated */
00613          return AST_CAUSE_INTERWORKING;
00614       case 488:   /* No codecs approved */
00615          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
00616       case 491:   /* Request pending */
00617          return AST_CAUSE_INTERWORKING;
00618       case 493:   /* Undecipherable */
00619          return AST_CAUSE_INTERWORKING;
00620       case 500:   /* Server internal failure */
00621          return AST_CAUSE_FAILURE;
00622       case 501:   /* Call rejected */
00623          return AST_CAUSE_FACILITY_REJECTED;
00624       case 502:   
00625          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
00626       case 503:   /* Service unavailable */
00627          return AST_CAUSE_CONGESTION;
00628       case 504:   /* Gateway timeout */
00629          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
00630       case 505:   /* SIP version not supported */
00631          return AST_CAUSE_INTERWORKING;
00632       case 600:   /* Busy everywhere */
00633          return AST_CAUSE_USER_BUSY;
00634       case 603:   /* Decline */
00635          return AST_CAUSE_CALL_REJECTED;
00636       case 604:   /* Does not exist anywhere */
00637          return AST_CAUSE_UNALLOCATED;
00638       case 606:   /* Not acceptable */
00639          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
00640       default:
00641          return AST_CAUSE_NORMAL;
00642    }
00643    /* Never reached */
00644    return 0;
00645 }

int init_req struct sip_request req,
int  sipmethod,
const char *  recip
 

Initialize SIP request.

Definition at line 150 of file sip3_compose.c.

00151 {
00152    /* Initialize a request */
00153         req->method = sipmethod;
00154    if (option_debug > 3)
00155       ast_log(LOG_DEBUG,"!!!!!! Size of request data in init_req: %d\n", (int) req->data_size);
00156    req->header[0] = req->data;
00157    snprintf(req->header[0], req->data_size, "%s %s SIP/2.0\r\n", sip_method2txt(sipmethod), recip);
00158    req->len = strlen(req->header[0]);
00159    req->headers++;
00160    return 0;
00161 }

int init_resp struct sip_request resp,
const char *  msg
 

Initialize SIP response, based on SIP request.

Definition at line 138 of file sip3_compose.c.

00139 {
00140    /* Initialize a response */
00141    resp->method = SIP_RESPONSE;
00142    resp->header[0] = resp->data;
00143    snprintf(resp->header[0], resp->data_size, "SIP/2.0 %s\r\n", msg);
00144    resp->len = strlen(resp->header[0]);
00145    resp->headers++;
00146    return 0;
00147 }

void initialize_initreq struct sip_pvt p,
struct sip_request req
 

void initreqprep struct sip_request req,
struct sip_pvt p,
int  sipmethod
 

const char* insecure2str int  port,
int  invite
const
 

void list_route struct sip_route route  ) 
 

int local_attended_transfer struct sip_pvt transferer,
struct sip_dual current,
struct sip_request req,
int  seqno
 

int lws2sws char *  msgbuf,
int  len
 

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 807 of file sip3_parse.c.

00808 {
00809    int h = 0, t = 0; 
00810    int lws = 0; 
00811 
00812    for (; h < len;) { 
00813       /* Eliminate all CRs */ 
00814       if (msgbuf[h] == '\r') { 
00815          h++; 
00816          continue; 
00817       } 
00818       /* Check for end-of-line */ 
00819       if (msgbuf[h] == '\n') { 
00820          /* Check for end-of-message */ 
00821          if (h + 1 == len) 
00822             break; 
00823          /* Check for a continuation line */ 
00824          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
00825             /* Merge continuation line */ 
00826             h++; 
00827             continue; 
00828          } 
00829          /* Propagate LF and start new line */ 
00830          msgbuf[t++] = msgbuf[h++]; 
00831          lws = 0;
00832          continue; 
00833       } 
00834       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
00835          if (lws) { 
00836             h++; 
00837             continue; 
00838          } 
00839          msgbuf[t++] = msgbuf[h++]; 
00840          lws = 1; 
00841          continue; 
00842       } 
00843       msgbuf[t++] = msgbuf[h++]; 
00844       if (lws) 
00845          lws = 0; 
00846    } 
00847    msgbuf[t] = '\0'; 
00848    return t; 
00849 }

void make_our_tag char *  tagbuf,
size_t  len
 

Make our SIP dialog tag.

Definition at line 729 of file sip3_dialog.c.

00730 {
00731    if (sipdebug)
00732       snprintf(tagbuf, len, "asterisk%08lx", ast_random());
00733    else
00734       snprintf(tagbuf, len, "%08lx", ast_random());
00735 }

int manager_sip_show_peer struct mansession s,
struct message m
 

int manager_sip_show_peers struct mansession s,
struct message m
 

int method_match enum sipmethod  id,
const char *  name
 

returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 152 of file sip3_parse.c.

00153 {
00154    int len = strlen(sip_methods[id].text);
00155    int l_name = name ? strlen(name) : 0;
00156 
00157    /* true if the string is long enough, and ends with whitespace, and matches */
00158    return (l_name >= len && name[len] < 33 &&
00159       !strncasecmp(sip_methods[id].text, name, len));
00160 }

char* nat2str int  nat  )  const
 

void parse_copy struct sip_request dst,
const struct sip_request src
 

void parse_moved_contact struct sip_pvt p,
struct sip_request req
 

int parse_ok_contact struct sip_pvt pvt,
struct sip_request req
 

enum parse_register_result parse_register_contact struct sip_pvt pvt,
struct sip_peer p,
struct sip_request req
 

void parse_request struct sip_request req  ) 
 

Parse a SIP message.

Note:
this function is used both on incoming and outgoing packets

Definition at line 964 of file sip3_parse.c.

00965 {
00966    char *c = req->data, **dst = req->header;
00967    int i = 0, lim = SIP_MAX_HEADERS - 1;
00968    int seqno = 0;
00969 
00970    req->header[0] = c;
00971    req->headers = -1;   /* mark that we are working on the header */
00972    for (; *c; c++) {
00973       if (*c == '\r')      /* remove \r */
00974          *c = '\0';
00975       else if (*c == '\n') { /* end of this line */
00976          *c = '\0';
00977          if (sipdebug && option_debug > 3)
00978             ast_log(LOG_DEBUG, "%7s %2d [%3d]: %s\n",
00979                req->headers < 0 ? "Header" : "Body",
00980                i, (int)strlen(dst[i]), dst[i]);
00981          if (ast_strlen_zero(dst[i]) && req->headers < 0) {
00982             req->headers = i; /* record number of header lines */
00983             dst = req->line;  /* start working on the body */
00984             i = 0;
00985             lim = SIP_MAX_LINES - 1;
00986          } else { /* move to next line, check for overflows */
00987             if (i++ >= lim)
00988                break;
00989          }
00990          dst[i] = c + 1; /* record start of next line */
00991       }
00992         }
00993    /* update count of header or body lines */
00994    if (req->headers >= 0)  /* we are in the body */
00995       req->lines = i;
00996    else {         /* no body */
00997       req->headers = i;
00998       req->lines = 0;
00999       req->line[0] = "";
01000    }
01001 
01002    if (*c)
01003       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
01004    /* Split up the first line parts */
01005    determine_firstline_parts(req);
01006    /* Determine the seqno of this request once and for all */
01007 
01008    ast_set_flag(req, SIP_PKT_PARSED);
01009 
01010    req->callid = get_header(req, "Call-ID");
01011    req->from = get_header(req, "From");
01012    req->to = get_header(req, "To");
01013    req->via = get_header(req, "Via");  /* Get the first via header only */
01014    req->cseqheader = get_header(req, "CSeq");  
01015    /* Seqno can be zero, but anyway... */
01016    if (!req->seqno && sscanf(req->cseqheader, "%d ", &seqno) != 1)
01017       req->seqno = seqno;
01018 }

unsigned int parse_sip_options struct sip_pvt pvt,
const char *  supported
 

int peer_status struct sip_peer peer,
char *  status,
int  statuslen
 

void print_codec_to_cli int  fd,
struct ast_codec_pref pref
 

void print_group int  fd,
ast_group_t  group,
int  crlf
 

Print call group and pickup group.

Definition at line 174 of file sip3_cliami.c.

00175 {
00176    char buf[256];
00177    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
00178 }

void realtime_update_peer const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expirey
 

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

Definition at line 112 of file sip3_objects.c.

00113 {
00114    char port[10];
00115    char ipaddr[INET_ADDRSTRLEN];
00116    char regseconds[20];
00117 
00118    char *sysname = ast_config_AST_SYSTEM_NAME;
00119    char *syslabel = NULL;
00120 
00121    time_t nowtime = time(NULL) + expiry;
00122    const char *fc = fullcontact ? "fullcontact" : NULL;
00123    
00124    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
00125    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
00126    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
00127    
00128    if (ast_strlen_zero(sysname)) /* No system name, disable this */
00129       sysname = NULL;
00130    else if (ast_test_flag(&global.flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
00131       syslabel = "regserver";
00132 
00133    if (fc)
00134       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
00135          "port", port, "regseconds", regseconds,
00136          "defaultuser", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
00137    else
00138       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
00139          "port", port, "regseconds", regseconds,
00140          "defaultuser", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
00141 }

void receive_message struct sip_pvt p,
struct sip_request req
 

void reg_source_db struct sip_peer peer  ) 
 

void register_peer_exten struct sip_peer peer,
int  onoff
 

enum check_auth_result register_verify struct sip_pvt p,
struct sockaddr_in *  sin,
struct sip_request req,
char *  uri
 

char* regstate2str enum sipregistrystate  regstate  )  const
 

Convert registration state status to string.

Definition at line 101 of file sip3_services.c.

00102 {
00103    switch(regstate) {
00104    case REG_STATE_FAILED:
00105       return "Failed";
00106    case REG_STATE_UNREGISTERED:
00107       return "Unregistered";
00108    case REG_STATE_REGSENT:
00109       return "Request Sent";
00110    case REG_STATE_AUTHSENT:
00111       return "Auth. Sent";
00112    case REG_STATE_REGISTERED:
00113       return "Registered";
00114    case REG_STATE_REJECTED:
00115       return "Rejected";
00116    case REG_STATE_TIMEOUT:
00117       return "Timeout";
00118    case REG_STATE_NOAUTH:
00119       return "No Authentication";
00120    default:
00121       return "Unknown";
00122    }
00123 }

int reqprep struct sip_request req,
struct sip_pvt p,
int  sipmethod,
int  seqno,
int  newbranch
 

int respprep struct sip_request resp,
struct sip_pvt p,
const char *  msg,
const struct sip_request req
 

int restart_monitor void   ) 
 

Start the channel monitor thread.

Definition at line 126 of file sip3_monitor.c.

00127 {
00128    /* If we're supposed to be stopped -- stay stopped */
00129    if (monitor_thread == AST_PTHREADT_STOP)
00130       return 0;
00131    /* Lock the monitor lock to keep the new monitor thread under control */
00132    ast_mutex_lock(&monlock);
00133    if (monitor_thread == pthread_self()) {
00134       ast_mutex_unlock(&monlock);
00135       ast_log(LOG_WARNING, "Cannot kill myself\n");
00136       return -1;
00137    }
00138    if (monitor_thread != AST_PTHREADT_NULL) {
00139       /* Wake up the thread */
00140       pthread_kill(monitor_thread, SIGURG);
00141    } else {
00142       /* Start a new monitor */
00143       if (ast_pthread_create_background(&monitor_thread, NULL, do_sip_monitor, NULL) < 0) {
00144          ast_mutex_unlock(&monlock);
00145          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
00146          return -1;
00147       }
00148    }
00149 
00150    /* Let the monitor run by itself now */
00151    ast_mutex_unlock(&monlock);
00152    return 0;
00153 }

int send_request struct sip_pvt p,
struct sip_request req,
enum xmittype  reliable,
int  seqno
 

int set_address_from_contact struct sip_pvt pvt  ) 
 

void set_destination struct sip_pvt p,
char *  uri
 

void set_device_defaults struct sip_peer peer  ) 
 

int sip_addheader struct ast_channel chan,
void *  data
 

int sip_addrcmp char *  name,
struct sockaddr_in *  sin
 

struct sip_pvt* sip_alloc ast_string_field  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method
 

Allocate SIP_PVT structure and set defaults.

Definition at line 803 of file sip3_dialog.c.

00805 {
00806    struct sip_dialog *dialog;
00807 
00808    if (!(dialog = ast_calloc(1, sizeof(*dialog))))
00809       return NULL;
00810 
00811    if (ast_string_field_init(dialog, 512)) {
00812       free(dialog);
00813       return NULL;
00814    }
00815    sipcounters.dialog_objects++;
00816    if (option_debug > 3)
00817       ast_log(LOG_DEBUG, "--DIALOGS-- Counter %d\n", sipcounters.dialog_objects);
00818 
00819       ast_mutex_init(&dialog->lock);
00820 
00821    dialog->method = intended_method;
00822    dialog->initid = -1;
00823    dialog->autokillid = -1;
00824    dialog->subscribed = NONE;
00825    dialog->stateid = -1;
00826    dialog->prefs = global.default_prefs;     /* Set default codecs for this call */
00827 
00828    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
00829       dialog->timer_t1 = global.t1default;   /* 500 ms Default SIP retransmission timer T1 (RFC 3261) */
00830 
00831    if (sin) {
00832       dialog->sa = *sin;
00833       if (sip_ouraddrfor(&dialog->sa.sin_addr, &dialog->ourip))
00834          dialog->ourip = sipnet.__ourip;
00835    } else
00836       dialog->ourip = sipnet.__ourip;
00837 
00838    /* Copy global flags to this PVT at setup. */
00839    ast_copy_flags(&dialog->flags[0], &global.flags[0], SIP_FLAGS_TO_COPY);
00840    ast_copy_flags(&dialog->flags[1], &global.flags[1], SIP_PAGE2_FLAGS_TO_COPY);
00841 
00842    ast_set2_flag(&dialog->flags[0], !global.recordhistory, SIP_NO_HISTORY);
00843 
00844    make_our_tag(dialog->tag, sizeof(dialog->tag));
00845    dialog->ocseq = INITIAL_CSEQ;
00846 
00847    /* Activate media streams */
00848    if (sip_method_needrtp(intended_method)) {
00849       if (!dialog_activate_media(dialog, &sipnet)) {
00850          ast_mutex_destroy(&dialog->lock);
00851          if (dialog->chanvars) {
00852             ast_variables_destroy(dialog->chanvars);
00853             dialog->chanvars = NULL;
00854          }
00855          free(dialog);
00856          return NULL;
00857       }
00858    }
00859 
00860    if (useglobal_nat && sin) {
00861       /* Setup NAT structure according to global settings if we have an address */
00862       ast_copy_flags(&dialog->flags[0], &global.flags[0], SIP_NAT);
00863       dialog->recv = *sin;
00864       do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
00865    }
00866 
00867    if (dialog->method != SIP_REGISTER)
00868       ast_string_field_set(dialog, fromdomain, global.default_fromdomain);
00869 
00870    build_via(dialog, TRUE);
00871    if (!callid)               /* Make sure we have a unique call ID */
00872       build_callid_pvt(dialog);
00873    else
00874       ast_string_field_set(dialog, callid, callid);
00875 
00876    dialogstatechange(dialog, DIALOG_STATE_TRYING); /* Set dialog state */
00877 
00878                      /* Assign default music on hold class */
00879    ast_string_field_set(dialog, mohinterpret, global.default_mohinterpret);
00880    ast_string_field_set(dialog, mohsuggest, global.default_mohsuggest);
00881    
00882    dialog->capability = global.capability;      /* Set default codec settings */
00883 
00884    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
00885        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
00886       dialog->noncodeccapability |= AST_RTP_DTMF;
00887 
00888    ast_string_field_set(dialog, context, global.default_context);
00889    dialog->allowtransfer = global.allowtransfer;   /* Default transfer mode */
00890 
00891    /* Add to active dialog list */
00892    dialoglist_lock();
00893    dialog->next = dialoglist;
00894    dialoglist = dialog;
00895    dialoglist_unlock();
00896    if (option_debug)
00897       ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_method2txt(intended_method), dialog->rtp ? "With RTP" : "No RTP");
00898    return dialog;
00899 }

void sip_cancel_destroy struct sip_pvt p  ) 
 

int sip_debug_test_addr const struct sockaddr_in *  addr  )  [inline]
 

See if we pass debug IP filter.

Definition at line 758 of file sip3_network.c.

00759 {
00760    if (!sipdebug)
00761       return 0;
00762    if (sipnet.debugaddr.sin_addr.s_addr) {
00763       if (((ntohs(sipnet.debugaddr.sin_port) != 0)
00764          && (sipnet.debugaddr.sin_port != addr->sin_port))
00765          || (sipnet.debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00766          return 0;
00767    }
00768    return 1;
00769 }

int sip_debug_test_pvt struct sip_pvt p  )  [inline]
 

void sip_destroy struct sip_pvt p  ) 
 

void sip_destroy_device struct sip_peer peer  ) 
 

int sip_devicestate void *  data  ) 
 

int sip_do_debug int  fd,
int  argc,
char *  argv[]
 

int sip_do_debug_ip int  fd,
int  argc,
char *  argv[]
 

int sip_do_debug_peer int  fd,
int  argc,
char *  argv[]
 

int sip_do_history int  fd,
int  argc,
char *  argv[]
 

int sip_do_reload enum channelreloadreason  reason  ) 
 

int sip_dtmfmode struct ast_channel chan,
void *  data
 

void sip_dump_history struct sip_pvt dialog  ) 
 

int sip_get_codec struct ast_channel chan  ) 
 

struct ast_udptl* sip_get_udptl_peer struct ast_channel chan  ) 
 

int sip_handle_t38_reinvite struct ast_channel chan,
struct sip_pvt pvt,
int  reinvite
 

T38 negotiation helper function

const char* sip_nat_mode const struct sip_pvt p  ) 
 

int sip_no_debug int  fd,
int  argc,
char *  argv[]
 

int sip_no_history int  fd,
int  argc,
char *  argv[]
 

int sip_notify int  fd,
int  argc,
char *  argv[]
 

int sip_park struct ast_channel chan1,
struct ast_channel chan2,
struct sip_request req,
int  seqno
 

void* sip_park_thread void *  stuff  ) 
 

void sip_peer_hold struct sip_pvt p,
int  hold
 

void sip_poke_all_peers void   ) 
 

Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?

Definition at line 239 of file sip3_pokedevice.c.

00240 {
00241    int ms = 0;
00242    
00243    if (!sipcounters.static_peers)   /* No peers, just give up */
00244       return;
00245 
00246    ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do {
00247       ASTOBJ_WRLOCK(iterator);
00248       if (iterator->pokeexpire > -1)
00249          ast_sched_del(sched, iterator->pokeexpire);
00250       ms += 100;
00251       iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
00252       ASTOBJ_UNLOCK(iterator);
00253    } while (0)
00254    );
00255 }

int sip_poke_noanswer void *  data  ) 
 

React to lack of answer to Qualify poke.

Definition at line 155 of file sip3_pokedevice.c.

00156 {
00157    struct sip_device *peer = data;
00158    
00159    peer->pokeexpire = -1;
00160    if (peer->lastms > -1) {
00161       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
00162       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
00163    }
00164    if (peer->call)
00165       sip_destroy(peer->call);
00166    peer->call = NULL;
00167    peer->lastms = -1;
00168    ast_device_state_changed("SIP/%s", peer->name);
00169    /* Try again quickly */
00170    peer->pokeexpire = ast_sched_add(sched, global.default_qualifycheck_notok, sip_poke_peer_s, peer);
00171    return 0;
00172 }

int sip_poke_peer struct sip_peer peer  ) 
 

int sip_poke_peer_s void *  data  ) 
 

Poke peer (send qualify to check if peer is alive and well).

Definition at line 93 of file sip3_pokedevice.c.

00094 {
00095    struct sip_device *peer = data;
00096 
00097    peer->pokeexpire = -1;
00098    sip_poke_peer(peer);
00099    return 0;
00100 }

int sip_prune_realtime int  fd,
int  argc,
char *  argv[]
 

Remove temporary realtime objects from memory (CLI).

Definition at line 2937 of file chan_sip3.c.

02938 {
02939    struct sip_device *device;
02940    int prunepeer = FALSE;
02941    int multi = FALSE;
02942    char *name = NULL;
02943    regex_t regexbuf;
02944 
02945    switch (argc) {
02946    case 4:
02947       if (!strcasecmp(argv[3], "peer"))
02948          return RESULT_SHOWUSAGE;
02949       if (!strcasecmp(argv[3], "like"))
02950          return RESULT_SHOWUSAGE;
02951       if (!strcasecmp(argv[3], "all")) {
02952          multi = TRUE;
02953          prunepeer = TRUE;
02954       } else {
02955          prunepeer = TRUE;
02956          name = argv[3];
02957       }
02958       break;
02959    case 5:
02960       if (!strcasecmp(argv[4], "like"))
02961          return RESULT_SHOWUSAGE;
02962       if (!strcasecmp(argv[3], "all"))
02963          return RESULT_SHOWUSAGE;
02964       if (!strcasecmp(argv[3], "like")) {
02965          multi = TRUE;
02966          name = argv[4];
02967          prunepeer = TRUE;
02968       } else if (!strcasecmp(argv[3], "peer")) {
02969          prunepeer = TRUE;
02970          if (!strcasecmp(argv[4], "all"))
02971             multi = TRUE;
02972          else
02973             name = argv[4];
02974       } else
02975          return RESULT_SHOWUSAGE;
02976       break;
02977    case 6:
02978       if (strcasecmp(argv[4], "like"))
02979          return RESULT_SHOWUSAGE;
02980       if (!strcasecmp(argv[3], "peer")) {
02981          prunepeer = TRUE;
02982          name = argv[5];
02983       } else
02984          return RESULT_SHOWUSAGE;
02985       break;
02986    default:
02987       return RESULT_SHOWUSAGE;
02988    }
02989 
02990    if (multi && name) {
02991       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
02992          return RESULT_SHOWUSAGE;
02993    }
02994 
02995    if (multi) {
02996       if (prunepeer) {
02997          int pruned = 0;
02998 
02999          ASTOBJ_CONTAINER_WRLOCK(&devicelist);
03000          ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do {
03001             ASTOBJ_RDLOCK(iterator);
03002             if (name && regexec(&regexbuf, iterator->name, 0, NULL, 0)) {
03003                ASTOBJ_UNLOCK(iterator);
03004                continue;
03005             };
03006             if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
03007                ASTOBJ_MARK(iterator);
03008                pruned++;
03009             }
03010             ASTOBJ_UNLOCK(iterator);
03011          } while (0) );
03012          if (pruned) {
03013             ASTOBJ_CONTAINER_PRUNE_MARKED(&devicelist, sip_destroy_device);
03014             ast_cli(fd, "%d peers pruned.\n", pruned);
03015          } else
03016             ast_cli(fd, "No peers found to prune.\n");
03017          ASTOBJ_CONTAINER_UNLOCK(&devicelist);
03018       }
03019    } else {
03020       if (prunepeer) {
03021          if ((device = ASTOBJ_CONTAINER_FIND_UNLINK(&devicelist, name))) {
03022             if (!ast_test_flag((&device->flags[1]), SIP_PAGE2_RTCACHEFRIENDS)) {
03023                ast_cli(fd, "Device '%s' is not a Realtime peer, cannot be pruned.\n", name);
03024                ASTOBJ_CONTAINER_LINK(&devicelist, device);
03025             } else
03026                ast_cli(fd, "Peer '%s' pruned.\n", name);
03027             device_unref(device);
03028          } else
03029             ast_cli(fd, "Device '%s' not found.\n", name);
03030       }
03031    }
03032 
03033    return RESULT_SUCCESS;
03034 }

const struct sockaddr_in* sip_real_dst const struct sip_pvt p  ) 
 

int sip_refer_allocate struct sip_pvt p  ) 
 

int sip_reg_timeout void *  data  ) 
 

int sip_register char *  value,
int  lineno
 

void sip_registry_destroy struct sip_registry reg  ) 
 

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 271 of file sip3_services.c.

00272 {
00273    /* Really delete */
00274    if (option_debug > 2)
00275       ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
00276 
00277    if (reg->call) {
00278       /* Clear registry before destroying to ensure
00279          we don't get reentered trying to grab the registry lock */
00280       reg->call->registry = NULL;
00281       if (option_debug > 2)
00282          ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
00283       sip_destroy(reg->call);
00284    }
00285    if (reg->expire > -1)
00286       ast_sched_del(sched, reg->expire);
00287    if (reg->timeout > -1)
00288       ast_sched_del(sched, reg->timeout);
00289    if (reg->peer)
00290       reg->peer->registry = NULL;      /* XXX ASTOBJ_UNREF ??? */
00291    ast_string_field_free_pools(reg);
00292    sipcounters.registry_objects--;
00293    free(reg);
00294    
00295 }

int sip_reload int  fd,
int  argc,
char *  argv[]
 

int sip_reregister void *  data  ) 
 

struct ast_frame* sip_rtp_read struct ast_channel ast,
struct sip_pvt p,
int *  faxdetect
 

void sip_scheddestroy struct sip_pvt p,
int  ms
 

void sip_send_all_registers void   ) 
 

Send all known registrations.

Note:
We space them out not to congest the network and the server

Definition at line 139 of file sip3_services.c.

00140 {
00141    int ms;
00142    int regspacing;
00143    if (!sipcounters.registry_objects)
00144       return;
00145    regspacing = expiry.default_expiry * 1000/sipcounters.registry_objects;
00146    if (regspacing > 100)
00147       regspacing = 100;
00148    ms = regspacing;
00149    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
00150       ASTOBJ_WRLOCK(iterator);
00151       if (iterator->expire > -1)
00152          ast_sched_del(sched, iterator->expire);
00153       ms += regspacing;
00154       iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
00155       ASTOBJ_UNLOCK(iterator);
00156    } while (0)
00157    );
00158 }

int sip_send_mwi_to_peer struct sip_peer peer  ) 
 

int sip_set_rtp_peer struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
int  codecs,
int  nat_active
 

Set the RTP peer for this call.

Definition at line 760 of file sip3_sdprtp.c.

00761 {
00762    struct sip_dialog *p;
00763    int changed = 0;
00764 
00765    p = chan->tech_pvt;
00766    if (!p) 
00767       return -1;
00768    dialog_lock(p, TRUE);
00769    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
00770       /* If we're destroyed, don't bother */
00771       dialog_lock(p, FALSE);
00772       return 0;
00773    }
00774 
00775    /* if this peer cannot handle reinvites of the media stream to devices
00776       that are known to be behind a NAT, then stop the process now
00777    */
00778    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
00779       dialog_lock(p, FALSE);
00780       return 0;
00781    }
00782 
00783    if (rtp) {
00784       changed |= ast_rtp_get_peer(rtp, &p->redirip);
00785    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
00786       memset(&p->redirip, 0, sizeof(p->redirip));
00787       changed = 1;
00788    }
00789    if (vrtp) {
00790       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
00791    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
00792       memset(&p->vredirip, 0, sizeof(p->vredirip));
00793       changed = 1;
00794    }
00795    if (codecs && (p->redircodecs != codecs)) {
00796       p->redircodecs = codecs;
00797       changed = 1;
00798    }
00799    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
00800       if (chan->_state != AST_STATE_UP) { /* We are in early state */
00801          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
00802             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
00803          if (option_debug)
00804             ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00805       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
00806          if (option_debug > 2) {
00807             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00808          }
00809          transmit_reinvite_with_sdp(p, FALSE);
00810       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
00811          if (option_debug > 2) {
00812             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00813          }
00814          /* We have a pending Invite. Send re-invite when we're done with the invite */
00815          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
00816       }
00817    }
00818    /* Reset lastrtprx timer */
00819    p->lastrtprx = p->lastrtptx = time(NULL);
00820    dialog_lock(p, FALSE);
00821    return 0;
00822 }

int sip_set_udptl_peer struct ast_channel chan,
struct ast_udptl udptl
 

int sip_show_channel int  fd,
int  argc,
char *  argv[]
 

int sip_show_channels int  fd,
int  argc,
char *  argv[]
 

int sip_show_domains int  fd,
int  argc,
char *  argv[]
 

CLI command to list local domains.

Definition at line 204 of file sip3_domain.c.

00205 {
00206    struct domain *d;
00207 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
00208 
00209    if (domains_configured()) {
00210       ast_cli(fd, "SIP Domain support not enabled.\n\n");
00211       return RESULT_SUCCESS;
00212    } else {
00213       ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
00214       AST_LIST_LOCK(&domain_list);
00215       AST_LIST_TRAVERSE(&domain_list, d, list)
00216          ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
00217             domain_mode_to_text(d->mode));
00218       AST_LIST_UNLOCK(&domain_list);
00219       ast_cli(fd, "\n");
00220       return RESULT_SUCCESS;
00221    }
00222 }

int sip_show_history int  fd,
int  argc,
char *  argv[]
 

int sip_show_inuse int  fd,
int  argc,
char *  argv[]
 

int sip_show_objects int  fd,
int  argc,
char *  argv[]
 

int sip_show_peer int  fd,
int  argc,
char *  argv[]
 

int sip_show_peers int  fd,
int  argc,
char *  argv[]
 

int sip_show_registry int  fd,
int  argc,
char *  argv[]
 

int sip_show_settings int  fd,
int  argc,
char *  argv[]
 

int sip_show_subscriptions int  fd,
int  argc,
char *  argv[]
 

int sip_show_user int  fd,
int  argc,
char *  argv[]
 

int sip_show_users int  fd,
int  argc,
char *  argv[]
 

int sip_sipredirect struct sip_pvt p,
const char *  dest
 

struct sip_peer * temp_peer const char *  name  ) 
 

char* transfermode2str enum transfermodes  mode  )  const
 

void transmit_fake_auth_response struct sip_pvt p,
struct sip_request req,
int  reliable
 

int transmit_info_with_digit struct sip_pvt p,
const char  digit
 

int transmit_info_with_vidupdate struct sip_pvt p  ) 
 

int transmit_invite struct sip_pvt p,
int  sipmethod,
int  sdp,
int  init
 

int transmit_message_with_text struct sip_pvt p,
const char *  text
 

int transmit_notify_with_mwi struct sip_pvt p,
int  newmsgs,
int  oldmsgs,
char *  vmexten
 

int transmit_notify_with_sipfrag struct sip_pvt p,
int  cseq,
char *  message,
int  terminate
 

int transmit_refer struct sip_pvt p,
const char *  dest
 

int transmit_register struct sip_registry r,
int  sipmethod,
const char *  auth,
const char *  authheader
 

Transmit register to SIP proxy or UA.

Definition at line 372 of file sip3_services.c.

00373 {
00374    struct sip_request *req;
00375    char from[256];
00376    char to[256];
00377    char tmp[80];
00378    char addr[80];
00379    struct sip_dialog *dialog;
00380 
00381    req = siprequest_alloc(SIP_MAX_PACKET, &sipnet);
00382 
00383    /* exit if we are already in process with this registrar ?*/
00384    if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
00385       ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
00386       return 0;
00387    }
00388 
00389    if (r->call) { /* We have a registration */
00390       if (!auth) {
00391          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
00392          return 0;
00393       } else {
00394          dialog = r->call;
00395          make_our_tag(dialog->tag, sizeof(dialog->tag)); /* create a new local tag for every register attempt */
00396          ast_string_field_free(dialog, theirtag);  /* forget their old tag, so we don't match tags when getting response */
00397       }
00398    } else {
00399       /* Build callid for registration if we haven't registered before */
00400       if (!r->callid_valid) {
00401          build_callid_registry(r, sipnet.__ourip, global.default_fromdomain);
00402          r->callid_valid = TRUE;
00403       }
00404       /* Allocate SIP packet for registration */
00405       if (!(dialog = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
00406          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
00407          return 0;
00408       }
00409       if (!ast_test_flag(&dialog->flags[0], SIP_NO_HISTORY))
00410          append_history(dialog, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
00411       /* Find address to hostname */
00412       if (create_addr(dialog, NULL, r->hostname, NULL)) {
00413          /* we have what we hope is a temporary network error,
00414           * probably DNS.  We need to reschedule a registration try */
00415          sip_destroy(dialog);
00416          if (r->timeout > -1) {
00417             ast_sched_del(sched, r->timeout);
00418             r->timeout = ast_sched_add(sched, global.reg_timeout*1000, sip_reg_timeout, r);
00419             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
00420          } else {
00421             r->timeout = ast_sched_add(sched, global.reg_timeout*1000, sip_reg_timeout, r);
00422             ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global.reg_timeout);
00423          }
00424          r->regattempts++;
00425          return 0;
00426       }
00427       /* Copy back Call-ID in case create_addr changed it */
00428       ast_string_field_set(r, callid, dialog->callid);
00429       if (r->portno)
00430          dialog->sa.sin_port = htons(r->portno);
00431       else  /* Set registry port to the port set from the peer definition/srv or default */
00432          r->portno = ntohs(dialog->sa.sin_port);
00433       ast_set_flag(&dialog->flags[0], SIP_OUTGOING);  /* Registration is outgoing call */
00434       r->call = dialog;       /* Save pointer to SIP packet */
00435       dialog->registry = ASTOBJ_REF(r);   /* Add pointer to registry in packet */
00436       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
00437          ast_string_field_set(dialog, peersecret, r->secret);
00438       if (!ast_strlen_zero(r->md5secret))
00439          ast_string_field_set(dialog, peermd5secret, r->md5secret);
00440       /* User name in this realm  
00441       - if authuser is set, use that, otherwise use username */
00442       if (!ast_strlen_zero(r->authuser)) {   
00443          ast_string_field_set(dialog, peername, r->authuser);
00444          ast_string_field_set(dialog, authname, r->authuser);
00445       } else if (!ast_strlen_zero(r->username)) {
00446          ast_string_field_set(dialog, peername, r->username);
00447          ast_string_field_set(dialog, authname, r->username);
00448          ast_string_field_set(dialog, fromuser, r->username);
00449       }
00450       if (!ast_strlen_zero(r->username))
00451          ast_string_field_set(dialog, username, r->username);
00452       /* Save extension in packet */
00453    
00454       /* If we have a peer relationship, fetch som more data from taht peer.
00455       */
00456       if (r->peer) {
00457          if (!ast_strlen_zero(r->peer->extra.fromdomain))
00458             ast_string_field_set(dialog, fromdomain, r->peer->extra.fromdomain);
00459       }
00460       ast_string_field_set(dialog, exten, r->contact);
00461 
00462       /*
00463         check which address we should use in our contact header 
00464         based on whether the remote host is on the external or
00465         internal network so we can register through nat
00466        */
00467       if (sip_ouraddrfor(&dialog->sa.sin_addr, &dialog->ourip))
00468          dialog->ourip = sipnet.bindaddr.sin_addr;
00469       build_contact(dialog);
00470    }
00471 
00472    /* set up a timeout */
00473    if (auth == NULL)  {
00474       if (r->timeout > -1) {
00475          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
00476          ast_sched_del(sched, r->timeout);
00477       }
00478       r->timeout = ast_sched_add(sched, global.reg_timeout * 1000, sip_reg_timeout, r);
00479       if (option_debug)
00480          ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
00481    }
00482 
00483    if (strchr(r->username, '@')) {
00484       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, dialog->tag);
00485       if (!ast_strlen_zero(dialog->theirtag))
00486          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, dialog->theirtag);
00487       else
00488          snprintf(to, sizeof(to), "<sip:%s>", r->username);
00489    } else {
00490       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, dialog->tohost, dialog->tag);
00491       if (!ast_strlen_zero(dialog->theirtag))
00492          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, dialog->tohost, dialog->theirtag);
00493       else
00494          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, dialog->tohost);
00495    }
00496    
00497    /* Fromdomain is what we are registering to, regardless of actual
00498       host name from SRV */
00499    snprintf(addr, sizeof(addr), "sip:%s", S_OR(dialog->fromdomain, r->hostname));
00500    ast_string_field_set(dialog, uri, addr);
00501 
00502    init_req(req, sipmethod, addr);
00503 
00504    /* Add to CSEQ */
00505    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_method2txt(sipmethod));
00506    req->seqno = dialog->ocseq = r->ocseq;
00507    build_via(dialog, TRUE);
00508    add_header(req, "Via", dialog->via);
00509    add_header(req, "From", from);
00510    add_header(req, "To", to);
00511    add_header(req, "Call-ID", dialog->callid);
00512    add_header(req, "CSeq", tmp);
00513    add_header(req, "User-Agent", global.useragent);
00514    append_maxforwards(req);
00515    
00516    if (auth)   /* Add auth header */
00517       add_header(req, authheader, auth);
00518    else if (!ast_strlen_zero(r->nonce)) {
00519       char digest[1024];
00520 
00521       /* We have auth data to reuse, build a digest header! */
00522       if (sipdebug)
00523          ast_log(LOG_DEBUG, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
00524       ast_string_field_set(dialog, realm, r->realm);
00525       ast_string_field_set(dialog, nonce, r->nonce);
00526       ast_string_field_set(dialog, domain, r->domain);
00527       ast_string_field_set(dialog, opaque, r->opaque);
00528       ast_string_field_set(dialog, qop, r->qop);
00529       dialog->noncecount = r->noncecount++;
00530 
00531       memset(digest, 0, sizeof(digest));
00532       if(!build_reply_digest(dialog, sipmethod, digest, sizeof(digest)))
00533          add_header(req, "Authorization", digest);
00534       else
00535          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
00536    
00537    }
00538 
00539    snprintf(tmp, sizeof(tmp), "%d", r->expiry);
00540    add_header(req, "Expires", tmp);
00541    add_header(req, "Contact", dialog->our_contact);
00542    add_header(req, "Event", "registration");
00543    add_header_contentLength(req, 0);
00544 
00545    initialize_initreq(dialog, req);
00546    if (sip_debug_test_pvt(dialog))
00547       ast_verbose("REGISTER %d headers, %d lines\n", dialog->initreq->headers, dialog->initreq->lines);
00548    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
00549    r->regattempts++; /* Another attempt */
00550    if (option_debug > 3)
00551       ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
00552    return send_request(dialog, req, XMIT_CRITICAL);
00553 }

int transmit_reinvite_with_sdp struct sip_pvt p  ) 
 

int transmit_reinvite_with_t38_sdp struct sip_pvt p  ) 
 

int transmit_request struct sip_pvt p,
int  sipmethod,
int  inc,
enum xmittype  reliable,
int  newbranch
 

int transmit_request_with_auth struct sip_pvt p,
int  sipmethod,
int  seqno,
enum xmittype  reliable,
int  newbranch
 

int transmit_response struct sip_pvt p,
const char *  msg,
const struct sip_request req
 

int transmit_response_reliable struct sip_pvt p,
const char *  msg,
const struct sip_request req
 

int transmit_response_with_allow struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable
 

int transmit_response_with_auth struct sip_pvt p,
const char *  msg,
const struct sip_request req,
const char *  rand,
enum xmittype  reliable,
const char *  header,
int  stale
 

int transmit_response_with_date struct sip_pvt p,
const char *  msg,
const struct sip_request req
 

int transmit_response_with_sdp struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable
 

int transmit_response_with_t38_sdp struct sip_pvt p,
char *  msg,
struct sip_request req,
int  retrans
 

int transmit_response_with_unsupported struct sip_pvt p,
const char *  msg,
const struct sip_request req,
const char *  unsupported
 

int transmit_sip_request struct sip_pvt p,
struct sip_request req
 

int transmit_state_notify struct sip_pvt p,
int  state,
int  full
 

void try_suggested_sip_codec struct sip_pvt p  ) 
 

int update_call_counter struct sip_pvt fup,
int  event
 

void update_peer struct sip_peer p,
int  expiry
 


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen