[svn-commits] oej: branch oej/codename-pineapple r46380 - in /team/oej/codename-pineapple/c...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Oct 28 10:57:10 MST 2006


Author: oej
Date: Sat Oct 28 12:57:09 2006
New Revision: 46380

URL: http://svn.digium.com/view/asterisk?rev=46380&view=rev
Log:
See, friends, see: 
 17222   74409  622008 channels/chan_sip.c
  9739   40664  336765 channels/chan_sip3.c

Cutting, cutting, cutting....


Modified:
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/sip3.h
    team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
    team/oej/codename-pineapple/channels/sip3/sip3_parse.c
    team/oej/codename-pineapple/channels/sip3/sip3_services.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=46380&r1=46379&r2=46380&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Sat Oct 28 12:57:09 2006
@@ -352,9 +352,6 @@
 /*! \brief The peer list: Peers and Friends */
 struct sip_device_list devicelist;
 
-/*! \brief  The register list: Other SIP proxys we register with and place calls to */
-struct sip_register_list regl;
-
 /* Forward declaration */
 static int temp_pvt_init(void *data);
 static void temp_pvt_cleanup(void *data);
@@ -409,17 +406,12 @@
 static int does_peer_need_mwi(struct sip_peer *peer);
 
 /*--- Dialog management */
-static struct sip_dialog *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
-				 int useglobal_nat, const int intended_method);
 GNURK void sip_destroy(struct sip_dialog *p);
 static void __sip_destroy(struct sip_dialog *p, int lockowner);
-static void __sip_ack(struct sip_dialog *p, int seqno, int resp, int sipmethod, int reset);
-static void __sip_pretend_ack(struct sip_dialog *p);
+static void __sip_ack(struct sip_dialog *dialog, int seqno, int resp, int sipmethod, int reset);
 static int __sip_semi_ack(struct sip_dialog *p, int seqno, int resp, int sipmethod);
 static int auto_congest(void *nothing);
 static int update_call_counter(struct sip_dialog *fup, int event);
-static int hangup_sip2cause(int cause);
-static const char *hangup_cause2sip(int cause);
 static void free_old_route(struct sip_route *route);
 static void list_route(struct sip_route *route);
 static void build_route(struct sip_dialog *p, struct sip_request *req, int backwards);
@@ -451,7 +443,6 @@
 static int sip_refer_allocate(struct sip_dialog *p);
 static void ast_quiet_chan(struct ast_channel *chan);
 static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
-static void do_setnat(struct sip_dialog *p, int natflags);
 
 /*--- Device monitoring and Device/extension state handling */
 static int cb_extensionstate(char *context, char* exten, int state, void *data);
@@ -502,18 +493,10 @@
 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey);
 static void update_peer(struct sip_peer *p, int expiry);
 
-/*--- Internal UA client handling (outbound registrations) */
-static void sip_registry_destroy(struct sip_registry *reg);
-static int sip_reregister(void *data);
-static int __sip_do_register(struct sip_registry *r);
-static int sip_reg_timeout(void *data);
-static void sip_send_all_registers(void);
-
 /*--- Parsing SIP requests and responses */
 static void append_date(struct sip_request *req);	/* Append date to SIP packet */
 static int determine_firstline_parts(struct sip_request *req);
 static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
-static char *get_in_brackets(char *tmp);
 static void extract_uri(struct sip_dialog *p, struct sip_request *req);
 static int get_refer_info(struct sip_dialog *transferer, struct sip_request *outgoing_req);
 static int get_also_info(struct sip_dialog *p, struct sip_request *oreq);
@@ -527,26 +510,17 @@
 static void free_old_route(struct sip_route *route);
 
 /*--- Constructing requests and responses */
-static void initialize_initreq(struct sip_dialog *p, struct sip_request *req);
-static int init_req(struct sip_request *req, int sipmethod, const char *recip);
 static int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch);
 static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
 static int init_resp(struct sip_request *resp, const char *msg);
 static int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req);
-static void build_via(struct sip_dialog *p);
 static int create_addr_from_peer(struct sip_dialog *r, struct sip_peer *peer);
-static int create_addr(struct sip_dialog *dialog, const char *opeer);
-static char *generate_random_string(char *buf, size_t size);
-static void build_callid_pvt(struct sip_dialog *pvt);
-static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
-static void make_our_tag(char *tagbuf, size_t len);
 static int add_text(struct sip_request *req, const char *text);
 static int add_digit(struct sip_request *req, char digit);
 static int add_vidupdate(struct sip_request *req);
 static void add_route(struct sip_request *req, struct sip_route *route);
 static void set_destination(struct sip_dialog *p, char *uri);
 static void append_date(struct sip_request *req);
-static void build_contact(struct sip_dialog *p);
 static void build_rpid(struct sip_dialog *p);
 
 /*------Request handling functions */
@@ -568,7 +542,6 @@
 static void handle_response_invite(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);
 static void handle_response_refer(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);
 static void handle_response_peerpoke(struct sip_dialog *p, int resp, struct sip_request *req);
-static int handle_response_register(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);
 static void handle_response(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);
 
 /*----- RTP interface functions */
@@ -605,7 +578,7 @@
 /*! \brief Initialize the initital request packet in the pvt structure.
  	This packet is used for creating replies and future requests in
 	a dialog */
-static void initialize_initreq(struct sip_dialog *p, struct sip_request *req)
+GNURK void initialize_initreq(struct sip_dialog *p, struct sip_request *req)
 {
 	if (p->initreq.headers && option_debug) {
 		ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
@@ -626,7 +599,7 @@
 }
 
 /*! \brief Build a Via header for a request */
-static void build_via(struct sip_dialog *p)
+GNURK void build_via(struct sip_dialog *p)
 {
 	/* Work around buggy UNIDEN UIP200 firmware */
 	const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
@@ -660,21 +633,21 @@
 }
 
 /*! \brief Append to SIP dialog history with arg list  */
-GNURK void append_history_full(struct sip_dialog *p, const char *fmt, ...)
+GNURK void append_history_full(struct sip_dialog *dialog, const char *fmt, ...)
 {
 	va_list ap;
 
-	if (!p)
+	if (!dialog)
 		return;
 	va_start(ap, fmt);
-	append_history_va(p, fmt, ap);
+	append_history_va(dialog, fmt, ap);
 	va_end(ap);
 
 	return;
 }
 
 /*! \brief Acknowledges receipt of a packet and stops retransmission */
-static void __sip_ack(struct sip_dialog *p, int seqno, int resp, int sipmethod, int reset)
+static void __sip_ack(struct sip_dialog *dialog, int seqno, int resp, int sipmethod, int reset)
 {
 	struct sip_pkt *cur, *prev = NULL;
 
@@ -684,19 +657,19 @@
 
 	msg = sip_method2txt(sipmethod);
 
-	ast_mutex_lock(&p->lock);
-	for (cur = p->packets; cur; prev = cur, cur = cur->next) {
+	ast_mutex_lock(&dialog->lock);
+	for (cur = dialog->packets; cur; prev = cur, cur = cur->next) {
 		if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
 			((ast_test_flag(cur, FLAG_RESPONSE)) || 
 			 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
-			if (!resp && (seqno == p->pendinginvite)) {
+			if (!resp && (seqno == dialog->pendinginvite)) {
 				if (option_debug)
-					ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
-				p->pendinginvite = 0;
+					ast_log(LOG_DEBUG, "Acked pending invite %d\n", dialog->pendinginvite);
+				dialog->pendinginvite = 0;
 			}
 			/* this is our baby */
 			res = TRUE;
-			UNLINK(cur, p->packets, prev);
+			UNLINK(cur, dialog->packets, prev);
 			if (cur->retransid > -1) {
 				if (sipdebug && option_debug > 3)
 					ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
@@ -707,26 +680,26 @@
 			break;
 		}
 	}
-	ast_mutex_unlock(&p->lock);
+	ast_mutex_unlock(&dialog->lock);
 	if (option_debug)
-		ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
-}
-
-/*! \brief Pretend to ack all packets
+		ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", dialog->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
+}
+
+/*! \brief Pretend to ack all packets - nothing to do with SIP_ACK (the method)
  * maybe the lock on p is not strictly necessary but there might be a race */
-static void __sip_pretend_ack(struct sip_dialog *p)
+GNURK void __sip_pretend_ack(struct sip_dialog *dialog)
 {
 	struct sip_pkt *cur = NULL;
 
-	while (p->packets) {
+	while (dialog->packets) {
 		int method;
-		if (cur == p->packets) {
+		if (cur == dialog->packets) {
 			ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_method2txt(cur->method));
 			return;
 		}
-		cur = p->packets;
+		cur = dialog->packets;
 		method = (cur->method) ? cur->method : find_sip_method(cur->data);
-		__sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method, FALSE);
+		__sip_ack(dialog, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method, FALSE);
 	}
 }
 
@@ -756,7 +729,7 @@
 }
 
 
-/*! \brief Copy SIP request, parse it */
+/*! \brief Copy SIP request, pre-parse it */
 GNURK void parse_copy(struct sip_request *dst, const struct sip_request *src)
 {
 	memset(dst, 0, sizeof(*dst));
@@ -773,67 +746,6 @@
 		snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n");
 		req->len += strlen(req->data + req->len);
 	}
-}
-
-/*! \brief Locate closing quote in a string, skipping escaped quotes.
- * optionally with a limit on the search.
- * start must be past the first quote.
- */
-static const char *find_closing_quote(const char *start, const char *lim)
-{
-        char last_char = '\0';
-        const char *s;
-        for (s = start; *s && s != lim; last_char = *s++) {
-                if (*s == '"' && last_char != '\\')
-                        break;
-        }
-        return s;
-}
-
-/*! \brief Pick out text in brackets from character string
-	\return pointer to terminated stripped string
-	\param 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
- */
-static char *get_in_brackets(char *tmp)
-{
-	const char *parse = tmp;
-	char *first_bracket;
-
-	/*
-	 * Skip any quoted text until we find the part in brackets.
-         * On any error give up and return the full string.
-         */
-        while ( (first_bracket = strchr(parse, '<')) ) {
-                char *first_quote = strchr(parse, '"');
-
-		if (!first_quote || first_quote > first_bracket)
-			break; /* no need to look at quoted part */
-		/* the bracket is within quotes, so ignore it */
-		parse = find_closing_quote(first_quote + 1, NULL);
-		if (!*parse) { /* not found, return full string ? */
-			/* XXX or be robust and return in-bracket part ? */
-			ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
-			break;
-		}
-		parse++;
-	}
-	if (first_bracket) {
-		char *second_bracket = strchr(first_bracket + 1, '>');
-		if (second_bracket) {
-			*second_bracket = '\0';
-			tmp = first_bracket + 1;
-		} else {
-			ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
-		}
-	}
-	return tmp;
 }
 
 /*! \brief Send SIP MESSAGE text within a call
@@ -970,62 +882,62 @@
 }
 
 /*! \brief Update peer data in database (if used) */
-static void update_peer(struct sip_peer *p, int expiry)
-{
-	int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
+static void update_peer(struct sip_peer *peer, int expiry)
+{
+	int rtcachefriends = ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
 	if (ast_test_flag(&global.flags[1], SIP_PAGE2_RTUPDATE) &&
-	    (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) {
-		realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry);
-	}
-}
-
-/*! \brief Support routine for find_peer */
+	    (ast_test_flag(&peer->flags[0], SIP_REALTIME) || rtcachefriends)) {
+		realtime_update_peer(peer->name, &peer->addr, peer->username, rtcachefriends ? peer->fullcontact : NULL, expiry);
+	}
+}
+
+/*! \brief Support routine for find_device */
 static int sip_addrcmp(char *name, struct sockaddr_in *sin)
 {
 	/* We know name is the first field, so we can cast */
-	struct sip_peer *p = (struct sip_peer *) name;
-	return 	!(!inaddrcmp(&p->addr, sin) || 
-					(ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) &&
-					(p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
+	struct sip_peer *peer = (struct sip_peer *) name;
+	return 	!(!inaddrcmp(&peer->addr, sin) || 
+					(ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) &&
+					(peer->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
 }
 
 /*! \brief Locate peer by name or ip address 
  *	This is used on incoming SIP message to find matching peer on ip
 	or outgoing message to find matching peer on name */
-GNURK struct sip_peer *find_device(const char *peer, struct sockaddr_in *sin, int realtime)
-{
-	struct sip_peer *p = NULL;
-
-	if (peer)
-		p = ASTOBJ_CONTAINER_FIND(&devicelist, peer);
+GNURK struct sip_peer *find_device(const char *device, struct sockaddr_in *sin, int realtime)
+{
+	struct sip_peer *peer = NULL;
+
+	if (device)
+		peer = ASTOBJ_CONTAINER_FIND(&devicelist, device);
 	else
-		p = ASTOBJ_CONTAINER_FIND_FULL(&devicelist, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
-
-	if (!p && realtime)
-		p = realtime_peer(peer, sin);
-
-	return p;
-}
-
-/*! \brief Set nat mode on the various data sockets */
-static void do_setnat(struct sip_dialog *p, int natflags)
+		peer = ASTOBJ_CONTAINER_FIND_FULL(&devicelist, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
+
+	if (!peer && realtime)
+		peer = realtime_peer(device, sin);
+
+	return peer;
+}
+
+/*! \brief Set nat mode on the various media streams */
+GNURK void do_setnat(struct sip_dialog *dialog, int natflags)
 {
 	const char *mode = natflags ? "On" : "Off";
 
-	if (p->rtp) {
+	if (dialog->rtp) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode);
-		ast_rtp_setnat(p->rtp, natflags);
-	}
-	if (p->vrtp) {
+		ast_rtp_setnat(dialog->rtp, natflags);
+	}
+	if (dialog->vrtp) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode);
-		ast_rtp_setnat(p->vrtp, natflags);
-	}
-	if (p->udptl) {
+		ast_rtp_setnat(dialog->vrtp, natflags);
+	}
+	if (dialog->udptl) {
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode);
-		ast_udptl_setnat(p->udptl, natflags);
+		ast_udptl_setnat(dialog->udptl, natflags);
 	}
 }
 
@@ -1133,7 +1045,7 @@
 /*! \brief create address structure from peer name
  *      Or, if peer not found, find it in the global DNS 
  *      returns TRUE (-1) on failure, FALSE on success */
-static int create_addr(struct sip_dialog *dialog, const char *opeer)
+GNURK int create_addr(struct sip_dialog *dialog, const char *opeer)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -1199,20 +1111,20 @@
 /*! \brief Scheduled congestion on a call */
 static int auto_congest(void *nothing)
 {
-	struct sip_dialog *p = nothing;
-
-	ast_mutex_lock(&p->lock);
-	p->initid = -1;
-	if (p->owner) {
+	struct sip_dialog *dialog = nothing;
+
+	ast_mutex_lock(&dialog->lock);
+	dialog->initid = -1;
+	if (dialog->owner) {
 		/* XXX fails on possible deadlock */
-		if (!ast_channel_trylock(p->owner)) {
-			ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name);
-			append_history(p, "Cong", "Auto-congesting (timer)");
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-			ast_channel_unlock(p->owner);
-		}
-	}
-	ast_mutex_unlock(&p->lock);
+		if (!ast_channel_trylock(dialog->owner)) {
+			ast_log(LOG_NOTICE, "Auto-congesting %s\n", dialog->owner->name);
+			append_history(dialog, "Cong", "Auto-congesting (timer)");
+			ast_queue_control(dialog->owner, AST_CONTROL_CONGESTION);
+			ast_channel_unlock(dialog->owner);
+		}
+	}
+	ast_mutex_unlock(&dialog->lock);
 	return 0;
 }
 
@@ -1293,32 +1205,6 @@
 			p->initid = ast_sched_add(sched, SIP_TRANS_TIMEOUT, auto_congest, p);
 	}
 	return res;
-}
-
-/*! \brief Destroy registry object
-	Objects created with the register= statement in static configuration */
-static void sip_registry_destroy(struct sip_registry *reg)
-{
-	/* Really delete */
-	if (option_debug > 2)
-		ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
-
-	if (reg->call) {
-		/* Clear registry before destroying to ensure
-		   we don't get reentered trying to grab the registry lock */
-		reg->call->registry = NULL;
-		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
-		sip_destroy(reg->call);
-	}
-	if (reg->expire > -1)
-		ast_sched_del(sched, reg->expire);
-	if (reg->timeout > -1)
-		ast_sched_del(sched, reg->timeout);
-	ast_string_field_free_pools(reg);
-	sipcounters.registry_objects--;
-	free(reg);
-	
 }
 
 /*! \brief Execute destruction of SIP dialog structure, release memory */
@@ -1520,167 +1406,6 @@
 	dialoglist_unlock();
 }
 
-/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
-static int hangup_sip2cause(int cause)
-{
-	/* Possible values taken from causes.h */
-
-	switch(cause) {
-		case 401:	/* Unauthorized */
-			return AST_CAUSE_CALL_REJECTED;
-		case 403:	/* Not found */
-			return AST_CAUSE_CALL_REJECTED;
-		case 404:	/* Not found */
-			return AST_CAUSE_UNALLOCATED;
-		case 405:	/* Method not allowed */
-			return AST_CAUSE_INTERWORKING;
-		case 407:	/* Proxy authentication required */
-			return AST_CAUSE_CALL_REJECTED;
-		case 408:	/* No reaction */
-			return AST_CAUSE_NO_USER_RESPONSE;
-		case 409:	/* Conflict */
-			return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
-		case 410:	/* Gone */
-			return AST_CAUSE_UNALLOCATED;
-		case 411:	/* Length required */
-			return AST_CAUSE_INTERWORKING;
-		case 413:	/* Request entity too large */
-			return AST_CAUSE_INTERWORKING;
-		case 414:	/* Request URI too large */
-			return AST_CAUSE_INTERWORKING;
-		case 415:	/* Unsupported media type */
-			return AST_CAUSE_INTERWORKING;
-		case 420:	/* Bad extension */
-			return AST_CAUSE_NO_ROUTE_DESTINATION;
-		case 480:	/* No answer */
-			return AST_CAUSE_NO_ANSWER;
-		case 481:	/* No answer */
-			return AST_CAUSE_INTERWORKING;
-		case 482:	/* Loop detected */
-			return AST_CAUSE_INTERWORKING;
-		case 483:	/* Too many hops */
-			return AST_CAUSE_NO_ANSWER;
-		case 484:	/* Address incomplete */
-			return AST_CAUSE_INVALID_NUMBER_FORMAT;
-		case 485:	/* Ambigous */
-			return AST_CAUSE_UNALLOCATED;
-		case 486:	/* Busy everywhere */
-			return AST_CAUSE_BUSY;
-		case 487:	/* Request terminated */
-			return AST_CAUSE_INTERWORKING;
-		case 488:	/* No codecs approved */
-			return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
-		case 491:	/* Request pending */
-			return AST_CAUSE_INTERWORKING;
-		case 493:	/* Undecipherable */
-			return AST_CAUSE_INTERWORKING;
-		case 500:	/* Server internal failure */
-			return AST_CAUSE_FAILURE;
-		case 501:	/* Call rejected */
-			return AST_CAUSE_FACILITY_REJECTED;
-		case 502:	
-			return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
-		case 503:	/* Service unavailable */
-			return AST_CAUSE_CONGESTION;
-		case 504:	/* Gateway timeout */
-			return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
-		case 505:	/* SIP version not supported */
-			return AST_CAUSE_INTERWORKING;
-		case 600:	/* Busy everywhere */
-			return AST_CAUSE_USER_BUSY;
-		case 603:	/* Decline */
-			return AST_CAUSE_CALL_REJECTED;
-		case 604:	/* Does not exist anywhere */
-			return AST_CAUSE_UNALLOCATED;
-		case 606:	/* Not acceptable */
-			return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
-		default:
-			return AST_CAUSE_NORMAL;
-	}
-	/* Never reached */
-	return 0;
-}
-
-/*! \brief Convert Asterisk hangup causes to SIP codes 
-\verbatim
- 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
-\endverbatim
-*/
-static const char *hangup_cause2sip(int cause)
-{
-	switch (cause) {
-		case AST_CAUSE_UNALLOCATED:		/* 1 */
-		case AST_CAUSE_NO_ROUTE_DESTINATION:	/* 3 IAX2: Can't find extension in context */
-		case AST_CAUSE_NO_ROUTE_TRANSIT_NET:	/* 2 */
-			return "404 Not Found";
-		case AST_CAUSE_CONGESTION:		/* 34 */
-		case AST_CAUSE_SWITCH_CONGESTION:	/* 42 */
-			return "503 Service Unavailable";
-		case AST_CAUSE_NO_USER_RESPONSE:	/* 18 */
-			return "408 Request Timeout";
-		case AST_CAUSE_NO_ANSWER:		/* 19 */
-			return "480 Temporarily unavailable";
-		case AST_CAUSE_CALL_REJECTED:		/* 21 */
-			return "403 Forbidden";
-		case AST_CAUSE_NUMBER_CHANGED:		/* 22 */
-			return "410 Gone";
-		case AST_CAUSE_NORMAL_UNSPECIFIED:	/* 31 */
-			return "480 Temporarily unavailable";
-		case AST_CAUSE_INVALID_NUMBER_FORMAT:
-			return "484 Address incomplete";
-		case AST_CAUSE_USER_BUSY:
-			return "486 Busy here";
-		case AST_CAUSE_FAILURE:
-			return "500 Server internal failure";
-		case AST_CAUSE_FACILITY_REJECTED:	/* 29 */
-			return "501 Not Implemented";
-		case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
-			return "503 Service Unavailable";
-		/* Used in chan_iax2 */
-		case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
-			return "502 Bad Gateway";
-		case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:	/* Can't find codec to connect to host */
-			return "488 Not Acceptable Here";
-			
-		case AST_CAUSE_NOTDEFINED:
-		default:
-			if (option_debug)
-				ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
-			return NULL;
-	}
-
-	/* Never reached */
-	return 0;
-}
-
-
 /*! \brief  sip_hangup: Hangup SIP call
  * Part of PBX interface, called from ast_hangup */
 static int sip_hangup(struct ast_channel *ast)
@@ -2303,7 +2028,7 @@
 }
 
 /*! \brief Generate 32 byte random string for callid's etc */
-static char *generate_random_string(char *buf, size_t size)
+GNURK char *generate_random_string(char *buf, size_t size)
 {
 	long val[4];
 	int x;
@@ -2316,7 +2041,7 @@
 }
 
 /*! \brief Build SIP Call-ID value for a non-REGISTER transaction */
-static void build_callid_pvt(struct sip_dialog *pvt)
+GNURK void build_callid_pvt(struct sip_dialog *pvt)
 {
 	char buf[33];
 
@@ -2324,147 +2049,6 @@
 	
 	ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
 
-}
-
-/*! \brief Build SIP Call-ID value for a REGISTER transaction */
-static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
-{
-	char buf[33];
-
-	const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
-
-	ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
-}
-
-/*! \brief Make our SIP dialog tag */
-static void make_our_tag(char *tagbuf, size_t len)
-{
-	if (sipdebug)
-		snprintf(tagbuf, len, "asterisk%08lx", ast_random());
-	else
-		snprintf(tagbuf, len, "%08lx", ast_random());
-}
-
-/*! \brief Allocate SIP_PVT structure and set defaults */
-static struct sip_dialog *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
-				 int useglobal_nat, const int intended_method)
-{
-	struct sip_dialog *p;
-
-	if (!(p = ast_calloc(1, sizeof(*p))))
-		return NULL;
-
-	if (ast_string_field_init(p, 512)) {
-		free(p);
-		return NULL;
-	}
-
-	ast_mutex_init(&p->lock);
-
-	p->method = intended_method;
-	p->initid = -1;
-	p->autokillid = -1;
-	p->subscribed = NONE;
-	p->stateid = -1;
-	p->prefs = global.default_prefs;		/* Set default codecs for this call */
-
-	if (intended_method != SIP_OPTIONS)	/* Peerpoke has it's own system */
-		p->timer_t1 = 500;	/* Default SIP retransmission timer T1 (RFC 3261) */
-
-	if (sin) {
-		p->sa = *sin;
-		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-			p->ourip = sipnet.__ourip;
-	} else
-		p->ourip = sipnet.__ourip;
-
-	/* Copy global flags to this PVT at setup. */
-	ast_copy_flags(&p->flags[0], &global.flags[0], SIP_FLAGS_TO_COPY);
-	ast_copy_flags(&p->flags[1], &global.flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-
-	ast_set2_flag(&p->flags[0], !global.recordhistory, SIP_NO_HISTORY);
-
-	p->branch = ast_random();	
-	make_our_tag(p->tag, sizeof(p->tag));
-	p->ocseq = INITIAL_CSEQ;
-
-	if (sip_method_needrtp(intended_method)) {
-		p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sipnet.bindaddr.sin_addr);
-		/* If the global videosupport flag is on, we always create a RTP interface for video */
-		if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
-			p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sipnet.bindaddr.sin_addr);
-		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
-			p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, sipnet.bindaddr.sin_addr);
-		if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
-			ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
-				ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
-			ast_mutex_destroy(&p->lock);
-			if (p->chanvars) {
-				ast_variables_destroy(p->chanvars);
-				p->chanvars = NULL;
-			}
-			free(p);
-			return NULL;
-		}
-		ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
-		ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
-		ast_rtp_settos(p->rtp, global.tos_audio);
-		if (p->vrtp) {
-			ast_rtp_settos(p->vrtp, global.tos_video);
-			ast_rtp_setdtmf(p->vrtp, 0);
-			ast_rtp_setdtmfcompensate(p->vrtp, 0);
-		}
-		if (p->udptl)
-			ast_udptl_settos(p->udptl, global.tos_audio);
-		p->rtptimeout = global.rtptimeout;
-		p->rtpholdtimeout = global.rtpholdtimeout;
-		p->rtpkeepalive = global.rtpkeepalive;
-		p->maxcallbitrate = global.default_maxcallbitrate;
-	}
-
-	if (useglobal_nat && sin) {
-		/* Setup NAT structure according to global settings if we have an address */
-		ast_copy_flags(&p->flags[0], &global.flags[0], SIP_NAT);
-		p->recv = *sin;
-		do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
-	}
-
-	if (p->method != SIP_REGISTER)
-		ast_string_field_set(p, fromdomain, global.default_fromdomain);
-	build_via(p);
-	if (!callid)
-		build_callid_pvt(p);
-	else
-		ast_string_field_set(p, callid, callid);
-	/* Assign default music on hold class */
-	ast_string_field_set(p, mohinterpret, global.default_mohinterpret);
-	ast_string_field_set(p, mohsuggest, global.default_mohsuggest);
-	p->capability = global.capability;
-	p->allowtransfer = global.allowtransfer;
-	if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
-	    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
-		p->noncodeccapability |= AST_RTP_DTMF;
-	if (p->udptl) {
-		p->t38.capability = global.t38_capability;
-		if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
-			p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
-		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
-			p->t38.capability |= T38FAX_UDP_EC_FEC;
-		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
-			p->t38.capability |= T38FAX_UDP_EC_NONE;
-		p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
-		p->t38.jointcapability = p->t38.capability;
-	}
-	ast_string_field_set(p, context, global.default_context);
-
-	/* Add to active dialog list */
-	dialoglist_lock();
-	p->next = dialoglist;
-	dialoglist = p;
-	dialoglist_unlock();
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_method2txt(intended_method), p->rtp ? "With RTP" : "No RTP");
-	return p;
 }
 
 /*! \brief Connect incoming SIP message to current dialog or create new dialog structure
@@ -2555,128 +2139,6 @@
 	}
 
 	return p;
-}
-
-/*! \brief Parse register=> line in sip.conf and add to registry */
-GNURK int sip_register(char *value, int lineno)
-{
-	struct sip_registry *reg;
-	char copy[256];
-	char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
-	char *porta=NULL;
-	char *contact=NULL;
-	char *stringp=NULL;
-	
-	if (!value)
-		return -1;
-	ast_copy_string(copy, value, sizeof(copy));
-	stringp=copy;
-	username = stringp;
-	hostname = strrchr(stringp, '@');
-	if (hostname)
-		*hostname++ = '\0';
-	if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
-		ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
-		return -1;
-	}
-	stringp = username;
-	username = strsep(&stringp, ":");
-	if (username) {
-		secret = strsep(&stringp, ":");
-		if (secret) 
-			authuser = strsep(&stringp, ":");
-	}
-	stringp = hostname;
-	hostname = strsep(&stringp, "/");
-	if (hostname) 
-		contact = strsep(&stringp, "/");
-	if (ast_strlen_zero(contact))
-		contact = "s";
-	stringp=hostname;
-	hostname = strsep(&stringp, ":");
-	porta = strsep(&stringp, ":");
-	
-	if (porta && !atoi(porta)) {
-		ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
-		return -1;
-	}
-	if (!(reg = ast_calloc(1, sizeof(*reg)))) {
-		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
-		return -1;
-	}
-
-	if (ast_string_field_init(reg, 256)) {
-		ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
-		free(reg);
-		return -1;
-	}
-
-	sipcounters.registry_objects++;
-	ASTOBJ_INIT(reg);
-	ast_string_field_set(reg, contact, contact);
-	if (username)
-		ast_string_field_set(reg, username, username);
-	if (hostname)
-		ast_string_field_set(reg, hostname, hostname);
-	if (authuser)
-		ast_string_field_set(reg, authuser, authuser);
-	if (secret)
-		ast_string_field_set(reg, secret, secret);
-	reg->expire = -1;
-	reg->expiry = expiry.default_expiry;
-	reg->timeout =  -1;
-	reg->refresh = expiry.default_expiry;
-	reg->portno = porta ? atoi(porta) : 0;
-	reg->callid_valid = FALSE;
-	reg->ocseq = INITIAL_CSEQ;
-	ASTOBJ_CONTAINER_LINK(&regl, reg);	/* Add the new registry entry to the list */
-	ASTOBJ_UNREF(reg,sip_registry_destroy);
-	return 0;
-}
-
-/*! \brief  Parse multiline SIP headers into one header */
-GNURK int lws2sws(char *msgbuf, int len) 
-{
-	int h = 0, t = 0; 
-	int lws = 0; 
-
-	for (; h < len;) { 
-		/* Eliminate all CRs */ 
-		if (msgbuf[h] == '\r') { 
-			h++; 
-			continue; 
-		} 
-		/* Check for end-of-line */ 
-		if (msgbuf[h] == '\n') { 
-			/* Check for end-of-message */ 
-			if (h + 1 == len) 
-				break; 
-			/* Check for a continuation line */ 
-			if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
-				/* Merge continuation line */ 
-				h++; 
-				continue; 
-			} 
-			/* Propagate LF and start new line */ 
-			msgbuf[t++] = msgbuf[h++]; 
-			lws = 0;
-			continue; 
-		} 
-		if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
-			if (lws) { 
-				h++; 
-				continue; 
-			} 
-			msgbuf[t++] = msgbuf[h++]; 
-			lws = 1; 
-			continue; 
-		} 
-		msgbuf[t++] = msgbuf[h++]; 
-		if (lws) 
-			lws = 0; 
-	} 
-	msgbuf[t] = '\0'; 
-	return t; 
 }
 
 /*! \brief Parse a SIP message 
@@ -2899,7 +2361,7 @@
 }
 
 /*! \brief Initialize SIP request */
-static int init_req(struct sip_request *req, int sipmethod, const char *recip)
+GNURK int init_req(struct sip_request *req, int sipmethod, const char *recip)
 {
 	/* Initialize a request */
 	memset(req, 0, sizeof(*req));
@@ -3568,7 +3030,7 @@
 }
 
 /*! \brief Build contact header - the contact header we send out */
-static void build_contact(struct sip_dialog *p)
+GNURK void build_contact(struct sip_dialog *p)
 {
 	/* Construct Contact: header */
 	if (sipnet_ourport() != STANDARD_SIP_PORT)	/* Needs to be 5060, according to the RFC */
@@ -4114,284 +3576,6 @@
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
 
-/*! \brief Convert registration state status to string */
-GNURK char *regstate2str(enum sipregistrystate regstate)
-{
-	switch(regstate) {
-	case REG_STATE_FAILED:
-		return "Failed";
-	case REG_STATE_UNREGISTERED:
-		return "Unregistered";
-	case REG_STATE_REGSENT:
-		return "Request Sent";
-	case REG_STATE_AUTHSENT:
-		return "Auth. Sent";
-	case REG_STATE_REGISTERED:
-		return "Registered";
-	case REG_STATE_REJECTED:
-		return "Rejected";
-	case REG_STATE_TIMEOUT:
-		return "Timeout";
-	case REG_STATE_NOAUTH:
-		return "No Authentication";
-	default:
-		return "Unknown";
-	}
-}
-
-/*! \brief Update registration with SIP Proxy */
-static int sip_reregister(void *data) 
-{
-	/* if we are here, we know that we need to reregister. */
-	struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data);
-
-	/* if we couldn't get a reference to the registry object, punt */
-	if (!r)
-		return 0;
-
-	if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 
-		append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
-	/* Since registry's are only added/removed by the the monitor thread, this
-	   may be overkill to reference/dereference at all here */
-	if (sipdebug)
-		ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
-
-	r->expire = -1;
-	__sip_do_register(r);
-	ASTOBJ_UNREF(r, sip_registry_destroy);
-	return 0;
-}
-
-/*! \brief Register with SIP proxy */
-static int __sip_do_register(struct sip_registry *r)
-{
-	int res;
-
-	res = transmit_register(r, SIP_REGISTER, NULL, NULL);
-	return res;
-}
-
-/*! \brief Registration timeout, register again */
-static int sip_reg_timeout(void *data)
-{
-
-	/* if we are here, our registration timed out, so we'll just do it over */
-	struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data);
-	struct sip_dialog *p;
-	int res;
-
-	/* if we couldn't get a reference to the registry object, punt */
-	if (!r)
-		return 0;
-
-	ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
-	if (r->call) {
-		/* Unlink us, destroy old call.  Locking is not relevant here because all this happens
-		   in the single SIP manager thread. */
-		p = r->call;
-		if (p->registry)
-			ASTOBJ_UNREF(p->registry, sip_registry_destroy);
-		r->call = NULL;
-		ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
-		/* Pretend to ACK anything just in case */
-		__sip_pretend_ack(p); /* XXX we need p locked, not sure we have */
-	}
-	/* If we have a limit, stop registration and give up */
-	if (global.regattempts_max && (r->regattempts > global.regattempts_max)) {
-		/* Ok, enough is enough. Don't try any more */
-		/* We could add an external notification here... 
-			steal it from app_voicemail :-) */
-		ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
-		r->regstate = REG_STATE_FAILED;
-	} else {
-		r->regstate = REG_STATE_UNREGISTERED;
-		r->timeout = -1;
-		res=transmit_register(r, SIP_REGISTER, NULL, NULL);
-	}
-	manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
-	ASTOBJ_UNREF(r, sip_registry_destroy);
-	return 0;
-}
-
-/*! \brief Transmit register to SIP proxy or UA */
-GNURK int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
-{
-	struct sip_request req;
-	char from[256];
-	char to[256];
-	char tmp[80];
-	char addr[80];
-	struct sip_dialog *p;
-
-	/* exit if we are already in process with this registrar ?*/
-	if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) {
-		ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
-		return 0;
-	}
-
-	if (r->call) {	/* We have a registration */
-		if (!auth) {
-			ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
-			return 0;
-		} else {
-			p = r->call;
-			make_our_tag(p->tag, sizeof(p->tag));	/* create a new local tag for every register attempt */
-			ast_string_field_free(p, theirtag);	/* forget their old tag, so we don't match tags when getting response */
-		}
-	} else {
-		/* Build callid for registration if we haven't registered before */
-		if (!r->callid_valid) {
-			build_callid_registry(r, sipnet.__ourip, global.default_fromdomain);
-			r->callid_valid = TRUE;
-		}
-		/* Allocate SIP packet for registration */
-		if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) {
-			ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
-			return 0;
-		}
-		if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
-			append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
-		/* Find address to hostname */
-		if (create_addr(p, r->hostname)) {
-			/* we have what we hope is a temporary network error,
-			 * probably DNS.  We need to reschedule a registration try */
-			sip_destroy(p);
-			if (r->timeout > -1) {
-				ast_sched_del(sched, r->timeout);
-				r->timeout = ast_sched_add(sched, global.reg_timeout*1000, sip_reg_timeout, r);
-				ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
-			} else {
-				r->timeout = ast_sched_add(sched, global.reg_timeout*1000, sip_reg_timeout, r);
-				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);
-			}
-			r->regattempts++;
-			return 0;
-		}

[... 1400 lines stripped ...]


More information about the svn-commits mailing list