[Asterisk-cvs] asterisk/channels chan_sip.c,1.612,1.613

markster at lists.digium.com markster at lists.digium.com
Tue Jan 4 22:59:41 CST 2005


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv15189/channels

Modified Files:
	chan_sip.c 
Log Message:
Merge sip notify fixes (bug #3243)


Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.612
retrieving revision 1.613
diff -u -d -r1.612 -r1.613
--- chan_sip.c	4 Jan 2005 06:21:05 -0000	1.612
+++ chan_sip.c	5 Jan 2005 05:04:43 -0000	1.613
@@ -115,6 +115,7 @@
 static char *channeltype = "SIP";
 static char *tdesc = "Session Initiation Protocol (SIP)";
 static char *config = "sip.conf";
+static char *notify_config = "sip_notify.conf";
 
 #define DEFAULT_SIP_PORT	5060	/* From RFC 2543 */
 #define SIP_MAX_PACKET		4096	/* Also from RFC 2543, should sub headers tho */
@@ -555,6 +556,9 @@
 static int externrefresh = 10;
 static struct ast_ha *localaddr;
 
+/* The list of manual NOTIFY types we know how to send */
+struct ast_config *notify_types;
+
 static struct ast_frame  *sip_read(struct ast_channel *ast);
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
@@ -614,6 +618,18 @@
 
 static void sip_destroy(struct sip_pvt *p);
 
+/*--- build_via: Build a Via header for a request ---*/
+static void build_via(struct sip_pvt *p, char *buf, int len)
+{
+	char iabuf[INET_ADDRSTRLEN];
+
+	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
+	if (ast_test_flag(p, SIP_NAT) != SIP_NAT_NEVER)
+		snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	else /* Work around buggy UNIDEN UIP200 firmware */
+		snprintf(buf, len, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+}
+
 /*--- ast_sip_ouraddrfor: NAT fix - decide which IP address to use for ASterisk server? ---*/
 /* Only used for outbound registrations */
 static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
@@ -2264,7 +2280,6 @@
 static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useglobal_nat)
 {
 	struct sip_pvt *p;
-	char iabuf[INET_ADDRSTRLEN];
 
 	p = malloc(sizeof(struct sip_pvt));
 	if (!p)
@@ -2318,11 +2333,7 @@
 	}
 
 	strncpy(p->fromdomain, default_fromdomain, sizeof(p->fromdomain) - 1);
-	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-	if (ast_test_flag(p, SIP_NAT) != SIP_NAT_NEVER)
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-	else
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	build_via(p, p->via, sizeof(p->via));
 	if (!callid)
 		build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
 	else
@@ -3122,7 +3133,6 @@
 	char stripped[80] ="";
 	char tmp[80];
 	char newto[256];
-	char iabuf[INET_ADDRSTRLEN];
 	char *c, *n;
 	char *ot, *of;
 
@@ -3137,10 +3147,7 @@
 	
 	if (newbranch) {
 		p->branch ^= rand();
-		if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-		else /* Some implementations (e.g. Uniden UIP200) can't handle rport being in the message!! */
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+		build_via(p, p->via, sizeof(p->via));
 	}
 	if (!strcasecmp(msg, "CANCEL")) {
 		c = p->initreq.rlPart2;	/* Use original URI */
@@ -3772,15 +3779,11 @@
 static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, char *authheader, char *vxml_url, char *distinctive_ring, char *osptoken, int addsipheaders, int init)
 {
 	struct sip_request req;
-	char iabuf[INET_ADDRSTRLEN];
 	
 	if (init) {
 		/* Bump branch even on initial requests */
 		p->branch ^= rand();
-		if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-		else /* Work around buggy UNIDEN UIP200 firmware */
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+		build_via(p, p->via, sizeof(p->via));
 		initreqprep(&req, p, cmd, vxml_url);
 	} else
 		reqprep(&req, p, cmd, 0, 1);
@@ -4018,7 +4021,7 @@
 		determine_firstline_parts(&p->initreq);
 	}
 
-	return send_request(p, req, 1, p->ocseq);
+	return send_request(p, req, 0, p->ocseq);
 }
 
 /*--- transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---*/
@@ -4149,7 +4152,6 @@
 	char tmp[80];
 	char via[80];
 	char addr[80];
-	char iabuf[INET_ADDRSTRLEN];
 	struct sip_pvt *p;
 
 	/* exit if we are already in process with this registrar ?*/
@@ -4259,11 +4261,7 @@
 	snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, cmd);
 	p->ocseq = r->ocseq;
 
-	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-	if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-		snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-	else /* Work around buggy UNIDEN UIP200 firmware */
-		snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	build_via(p, via, sizeof(via));
 	add_header(&req, "Via", via);
 	add_header(&req, "From", from);
 	add_header(&req, "To", to);
@@ -6135,23 +6133,50 @@
 	return c;
 }
 
-/*--- complete_sippeer: Support routine for 'sip reboot' CLI ---*/
-static char *complete_sippeer(char *line, char *word, int pos, int state)
+/*--- complete_sipnotify: Support routine for 'sip notify' CLI ---*/
+static char *complete_sipnotify(char *line, char *word, int pos, int state)
 {
-	int which=0;
 	char *c = NULL;
 
-	ASTOBJ_CONTAINER_TRAVERSE(&peerl, !c, do {
-		/* locking of the ASTOBJ is not required because I only compare the name */
-		if (!strncasecmp(word, iterator->name, strlen(word))) {
-			if (++which > state) {
-				c = strdup(iterator->name);
+	if (pos == 2) {
+		int which = 0;
+		char *cat;
+
+		/* do completion for notify type */
+
+		if (!notify_types)
+			return NULL;
+		
+		cat = ast_category_browse(notify_types, NULL);
+		while(cat) {
+			if (!strncasecmp(word, cat, strlen(word))) {
+				if (++which > state) {
+					c = strdup(cat);
+					break;
+				}
 			}
+			cat = ast_category_browse(notify_types, cat);
 		}
-	
-	} while(0) );
+		return c;
+	}
 
-	return c;
+	if (pos > 2) {
+		int which = 0;
+
+		/* do completion for peer name */
+
+		ASTOBJ_CONTAINER_TRAVERSE(&peerl, !c, do {
+			/* locking of the ASTOBJ is not required because I only compare the name */
+			if (!strncasecmp(word, iterator->name, strlen(word))) {
+				if (++which > state) {
+					c = strdup(iterator->name);
+				}
+			}
+		} while(0) );
+		return c;
+	}
+
+	return NULL;
 }
 
 /*--- sip_show_channel: Show details of one call ---*/
@@ -6406,72 +6431,57 @@
 
 static int sip_notify(int fd, int argc, char *argv[])
 {
-	struct sip_pvt *p;
-	struct sip_request req;
-	struct ast_config *cfg;
-	struct ast_variable *var;
-	char *cat;
-	char name[256] = "";
-	char type[256] = "";
-	char iabuf[INET_ADDRSTRLEN];
-	char foundtype = 0;
+	struct ast_variable *varlist;
+	int i;
 
-	if (argc != 4) {
+	if (argc < 4)
 		return RESULT_SHOWUSAGE;
-	} else {
-		p = sip_alloc(NULL, NULL, 0);
-		if (!p) {
-			ast_log(LOG_WARNING, "Unable to build sip pvt data for reboot\n");
-			return -1;
-		}
-		strncpy(type,argv[2],sizeof(type) - 1);
-		cfg = ast_load("sip_notify.conf");
 
-		if (!cfg) {
-			ast_log(LOG_WARNING, "No sip_notify.conf file :\n");
-			return RESULT_SUCCESS;
-		}
+	if (!notify_types) {
+		ast_cli(fd, "No %s file found, or no types listed there\n", notify_config);
+		return RESULT_FAILURE;
+	}
 
-		initreqprep(&req, p, "NOTIFY", NULL);
+	varlist = ast_variable_browse(notify_types, argv[2]);
 
-		cat = ast_category_browse(cfg, NULL);
-		while(cat) {
-			if (!strcasecmp(cat, type)) {
-				foundtype = 1;
+	if (!varlist) {
+		ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]);
+		return RESULT_FAILURE;
+	}
 
-				var = ast_variable_browse(cfg, cat);
-				while (var) {
-					add_header(&req, var->name, var->value);
-					var = var->next;
-				}
-			}
-			cat = ast_category_browse(cfg, cat);
-		}
-		ast_destroy(cfg);
+	for (i = 3; i < argc; i++) {
+		struct sip_pvt *p;
+		struct sip_request req;
+		struct ast_variable *var;
 
-		if (foundtype == 0) {
-			ast_log(LOG_WARNING, "Unable to find notify enter '%s'\n",argv[2]);
-			return RESULT_SUCCESS;
+		p = sip_alloc(NULL, NULL, 0);
+		if (!p) {
+			ast_log(LOG_WARNING, "Unable to build sip pvt data for notify\n");
+			return RESULT_FAILURE;
 		}
 
-		strncpy(name, argv[3], sizeof(name) - 1);
-		if (create_addr(p, name)) {
+		if (create_addr(p, argv[i])) {
 			/* Maybe they're not registered, etc. */
 			sip_destroy(p);
-			return 0;
+			ast_cli(fd, "Could not create address fo '%s'\n", argv[i]);
+			continue;
 		}
+
+		initreqprep(&req, p, "NOTIFY", NULL);
+
+		for (var = varlist; var; var = var->next)
+			add_header(&req, var->name, var->value);
+
 		/* Recalculate our side, and recalculate Call ID */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
+		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
-		/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-		if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-		else /* UNIDEN UIP200 bug */
-			snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+		build_via(p, p->via, sizeof(p->via));
 		build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
-		transmit_sip_request(p,&req);
+		ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
+		transmit_sip_request(p, &req);
 		sip_scheddestroy(p, 15000);
 	}
+
 	return RESULT_SUCCESS;
 }
 /*--- sip_do_history: Enable SIP History logging (CLI) ---*/
@@ -6498,6 +6508,7 @@
 
 /*--- sip_no_debug: Disable SIP Debugging in CLI ---*/
 static int sip_no_debug(int fd, int argc, char *argv[])
+
 {
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
@@ -6694,8 +6705,9 @@
 
 
 static char notify_usage[] =
-"Usage: sip notify <type> <peer>\n"
-"       Send a notify command to a remote SIP peer\n";
+"Usage: sip notify <type> <peer> [<peer>...]\n"
+"       Send a NOTIFY message to a SIP peer or peers\n"
+"       Message types are defined in sip_notify.conf\n";
 
 static char show_users_usage[] = 
 "Usage: sip show users\n"
@@ -6764,7 +6776,7 @@
 "       Shows status of known SIP objects\n";
 
 static struct ast_cli_entry  cli_notify =
-	{ { "sip", "notify", NULL }, sip_notify, "Send a notify packet to a SIP peer", notify_usage, complete_sippeer };
+	{ { "sip", "notify", NULL }, sip_notify, "Send a notify packet to a SIP peer", notify_usage, complete_sipnotify };
 static struct ast_cli_entry  cli_show_objects = 
 	{ { "sip", "show", "objects", NULL }, sip_show_objects, "Show all SIP object allocations", show_objects_usage };
 static struct ast_cli_entry  cli_show_users = 
@@ -8052,7 +8064,6 @@
 	/* Called with peerl lock, but releases it */
 	struct sip_pvt *p;
 	char name[256] = "";
-	char iabuf[INET_ADDRSTRLEN];
 	int newmsgs, oldmsgs;
 
 	/* Check for messages */
@@ -8080,11 +8091,7 @@
 	/* Recalculate our side, and recalculate Call ID */
 	if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
 		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
-	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-	if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-	else /* UNIDEN UIP200 bug */
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	build_via(p, p->via, sizeof(p->via));
 	build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
 	/* Send MWI */
 	ast_set_flag(p, SIP_OUTGOING);
@@ -8275,7 +8282,6 @@
 static int sip_poke_peer(struct sip_peer *peer)
 {
 	struct sip_pvt *p;
-	char iabuf[INET_ADDRSTRLEN];
 	if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
 		/* IF we have no IP, or this isn't to be monitored, return
 		  imeediately after clearing things out */
@@ -8311,11 +8317,7 @@
 	/* Recalculate our side, and recalculate Call ID */
 	if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
 		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
-	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-	if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-	else
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	build_via(p, p->via, sizeof(p->via));
 	build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
 
 	if (peer->pokeexpire > -1)
@@ -8389,7 +8391,6 @@
 	struct ast_channel *tmpc = NULL;
 	char *ext, *host;
 	char tmp[256] = "";
-	char iabuf[INET_ADDRSTRLEN];
 	char *dest = data;
 
 	oldformat = format;
@@ -8435,11 +8436,7 @@
 	/* Recalculate our side, and recalculate Call ID */
 	if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
 		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
-	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
-	if (ast_test_flag(p, SIP_NAT) & SIP_NAT_RFC3581)
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
-	else /* UNIDEN bug */
-		snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
+	build_via(p, p->via, sizeof(p->via));
 	build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
 	
 	/* We have an extension to call, don't use the full contact here */
@@ -9159,6 +9156,12 @@
 
 	/* Release configuration from memory */
 	ast_destroy(cfg);
+
+	/* Load the list of manual NOTIFY types to support */
+	if (notify_types)
+		ast_destroy(notify_types);
+	notify_types = ast_load(notify_config);
+
 	return 0;
 }
 




More information about the svn-commits mailing list