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

markster at lists.digium.com markster at lists.digium.com
Tue Jan 4 00:15:56 CST 2005


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

Modified Files:
	chan_sip.c 
Log Message:
Allow generic sip notify (bug #3231)


Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.611
retrieving revision 1.612
diff -u -d -r1.611 -r1.612
--- chan_sip.c	4 Jan 2005 06:16:04 -0000	1.611
+++ chan_sip.c	4 Jan 2005 06:21:05 -0000	1.612
@@ -107,7 +107,7 @@
 #define DEFAULT_RETRANS		1000		/* How frequently to retransmit */
 #define MAX_RETRANS		5		/* Try only 5 times for retransmissions */
 
-						/* SIP Debug		*/
+
 #define DEBUG_READ	0			/* Recieved data	*/
 #define DEBUG_SEND	1			/* Transmit data	*/
 
@@ -4007,6 +4007,20 @@
 	return send_request(p, &req, 1, p->ocseq);
 }
 
+static int transmit_sip_request(struct sip_pvt *p,struct sip_request *req)
+{
+	if (!p->initreq.headers) {
+		/* Use this as the basis */
+		copy_request(&p->initreq, req);
+		parse(&p->initreq);
+		if (sip_debug_test_pvt(p))
+			ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
+		determine_firstline_parts(&p->initreq);
+	}
+
+	return send_request(p, req, 1, p->ocseq);
+}
+
 /*--- transmit_notify_with_sipfrag: Notify a transferring party of the status of trasnfer ---*/
 /*      Apparently the draft SIP REFER structure was too simple, so it was decided that the
  *      status of transfers also needed to be sent via NOTIFY instead of just the 202 Accepted
@@ -6121,6 +6135,25 @@
 	return c;
 }
 
+/*--- complete_sippeer: Support routine for 'sip reboot' CLI ---*/
+static char *complete_sippeer(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);
+			}
+		}
+	
+	} while(0) );
+
+	return c;
+}
+
 /*--- sip_show_channel: Show details of one call ---*/
 static int sip_show_channel(int fd, int argc, char *argv[])
 {
@@ -6371,6 +6404,76 @@
 	return RESULT_SUCCESS;
 }
 
+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;
+
+	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;
+		}
+
+		initreqprep(&req, p, "NOTIFY", NULL);
+
+		cat = ast_category_browse(cfg, NULL);
+		while(cat) {
+			if (!strcasecmp(cat, type)) {
+				foundtype = 1;
+
+				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);
+
+		if (foundtype == 0) {
+			ast_log(LOG_WARNING, "Unable to find notify enter '%s'\n",argv[2]);
+			return RESULT_SUCCESS;
+		}
+
+		strncpy(name, argv[3], sizeof(name) - 1);
+		if (create_addr(p, name)) {
+			/* Maybe they're not registered, etc. */
+			sip_destroy(p);
+			return 0;
+		}
+		/* 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_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
+		transmit_sip_request(p,&req);
+		sip_scheddestroy(p, 15000);
+	}
+	return RESULT_SUCCESS;
+}
 /*--- sip_do_history: Enable SIP History logging (CLI) ---*/
 static int sip_do_history(int fd, int argc, char *argv[])
 {
@@ -6590,6 +6693,9 @@
 	
 
 
+static char notify_usage[] =
+"Usage: sip notify <type> <peer>\n"
+"       Send a notify command to a remote SIP peer\n";
 
 static char show_users_usage[] = 
 "Usage: sip show users\n"
@@ -6657,7 +6763,8 @@
 "Usage: sip show objects\n" 
 "       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 };
 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 = 
@@ -9391,6 +9498,7 @@
 			ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
 			return -1;
 		}
+		ast_cli_register(&cli_notify);
 		ast_cli_register(&cli_show_users);
 		ast_cli_register(&cli_show_objects);
 		ast_cli_register(&cli_show_subscriptions);
@@ -9433,6 +9541,7 @@
 	ast_unregister_application(app_dtmfmode);
 	ast_unregister_application(app_sipaddheader);
 	ast_unregister_application(app_sipgetheader);
+	ast_cli_unregister(&cli_notify);
 	ast_cli_unregister(&cli_show_users);
 	ast_cli_unregister(&cli_show_objects);
 	ast_cli_unregister(&cli_show_channels);




More information about the svn-commits mailing list