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

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Nov 14 14:27:21 MST 2006


Author: oej
Date: Tue Nov 14 15:27:21 2006
New Revision: 47624

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47624
Log:
Moving around stuff

Added:
    team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c   (with props)
Modified:
    team/oej/codename-pineapple/channels/Makefile
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/Makefile
    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_refer.c
    team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c
    team/oej/codename-pineapple/channels/sip3/sip3_utils.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h

Modified: team/oej/codename-pineapple/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/Makefile?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/Makefile (original)
+++ team/oej/codename-pineapple/channels/Makefile Tue Nov 14 15:27:21 2006
@@ -16,7 +16,7 @@
 SIP3_MODULES=chan_sip3.o sip3/sip3_network.o sip3/sip3_subscribe.o sip3/sip3_refer.o sip3/sip3_domain.o \
 	sip3/sip3_callerid.o sip3/sip3_auth.o sip3/sip3_sdprtp.o sip3/sip3_config.o \
 	sip3/sip3_cliami.o sip3/sip3_dialog.o sip3/sip3_services.o sip3/sip3_compose.o \
-	sip3/sip3_parse.o sip3/sip3_utils.o
+	sip3/sip3_parse.o sip3/sip3_utils.o sip3/sip3_pokedevice.o
 
 ifeq ($(OSARCH),OpenBSD)
   PTLIB=-lpt_OpenBSD_x86_r

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Tue Nov 14 15:27:21 2006
@@ -474,7 +474,6 @@
 
 /*--- Dialog management */
 static int auto_congest(void *nothing);
-static int update_call_counter(struct sip_dialog *fup, int event);
 static void list_route(struct sip_route *route);
 static void build_route(struct sip_dialog *p, struct sip_request *req, int backwards);
 static enum check_auth_result register_verify(struct sip_dialog *p, struct sockaddr_in *sin,
@@ -502,9 +501,6 @@
 /*--- Device monitoring and Device/extension state handling */
 static int cb_extensionstate(char *context, char* exten, int state, void *data);
 static int sip_devicestate(void *data);
-static int sip_poke_noanswer(void *data);
-static int sip_poke_peer(struct sip_peer *peer);
-static void sip_poke_all_peers(void);
 
 /*--- Applications, functions, CLI and manager command helpers */
 GNURK int sip_notify(int fd, int argc, char *argv[]);
@@ -524,11 +520,8 @@
 
 /*--- Device object handling */
 static struct sip_peer *temp_peer(const char *name);
-static int update_call_counter(struct sip_dialog *fup, int event);
-static int sip_poke_peer(struct sip_peer *peer);
 static struct sip_peer *temp_peer(const char *name);
 static void register_peer_exten(struct sip_peer *peer, int onoff);
-static int sip_poke_peer_s(void *data);
 static enum parse_register_result parse_register_contact(struct sip_dialog *pvt, struct sip_peer *p, struct sip_request *req);
 
 /* Realtime device support */
@@ -561,7 +554,6 @@
 /*------Response handling functions */
 static void handle_response_invite(struct sip_dialog *p, int resp, char *rest, struct sip_request *req);
 static void handle_response_refer(struct sip_dialog *p, int resp, char *rest, struct sip_request *req);
-static void handle_response_peerpoke(struct sip_dialog *p, int resp, struct sip_request *req);
 static void handle_response(struct sip_dialog *p, int resp, char *rest, struct sip_request *req);
 
 /*------ T38 Support --------- */
@@ -807,7 +799,7 @@
 /*! \brief Destroy device object from memory */
 GNURK void sip_destroy_device(struct sip_peer *device)
 {
-	logdebug(3, "Destroying SIP %s %s\n", device->type & SIP_USER ? "user" : "peer", device->name);
+	logdebug(3, "Destroying SIP device %s\n", device->name);
 	//if (option_debug > 2)
 		//ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type & SIP_USER ? "user" : "peer", device->name);
 
@@ -1203,7 +1195,7 @@
  *	-1 on rejection of call
  *		
  */
-static int update_call_counter(struct sip_dialog *fup, int event)
+GNURK int update_call_counter(struct sip_dialog *fup, int event)
 {
 	char name[256];
 	int outgoing = ast_test_flag(&fup->flags[0], SIP_OUTGOING);
@@ -1694,8 +1686,7 @@
 		break;
 	case AST_CONTROL_BUSY:
 		if (ast->_state != AST_STATE_UP) {
-			transmit_response(p, "486 Busy Here", &p->initreq);
-			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			transmit_final_response(p, "486 Busy Here", &p->initreq, XMIT_RELIABLE);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
 		}
@@ -1703,8 +1694,7 @@
 		break;
 	case AST_CONTROL_CONGESTION:
 		if (ast->_state != AST_STATE_UP) {
-			transmit_response(p, "503 Service Unavailable", &p->initreq);
-			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			transmit_final_response(p, "503 Service Unavailable", &p->initreq, XMIT_RELIABLE);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
 		}
@@ -2423,167 +2413,6 @@
 	return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
 }
 
-/*! \brief Used in the SUBSCRIBE notification subsystem */
-GNURK int transmit_state_notify(struct sip_dialog *p, int state, int full, int timeout)
-{
-	char tmp[4000], from[256], to[256];
-	char *t = tmp, *c, *mfrom, *mto;
-	size_t maxbytes = sizeof(tmp);
-	struct sip_request req;
-	char hint[AST_MAX_EXTENSION];
-	char *statestring = "terminated";
-	const struct cfsubscription_types *subscriptiontype;
-	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
-	char *pidfstate = "--";
-	char *pidfnote= "Ready";
-
-	memset(from, 0, sizeof(from));
-	memset(to, 0, sizeof(to));
-	memset(tmp, 0, sizeof(tmp));
-
-	switch (state) {
-	case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
-		statestring = (global.notifyringing) ? "early" : "confirmed";
-		local_state = NOTIFY_INUSE;
-		pidfstate = "busy";
-		pidfnote = "Ringing";
-		break;
-	case AST_EXTENSION_RINGING:
-		statestring = "early";
-		local_state = NOTIFY_INUSE;
-		pidfstate = "busy";
-		pidfnote = "Ringing";
-		break;
-	case AST_EXTENSION_INUSE:
-		statestring = "confirmed";
-		local_state = NOTIFY_INUSE;
-		pidfstate = "busy";
-		pidfnote = "On the phone";
-		break;
-	case AST_EXTENSION_BUSY:
-		statestring = "confirmed";
-		local_state = NOTIFY_CLOSED;
-		pidfstate = "busy";
-		pidfnote = "On the phone";
-		break;
-	case AST_EXTENSION_UNAVAILABLE:
-		statestring = "confirmed";
-		local_state = NOTIFY_CLOSED;
-		pidfstate = "away";
-		pidfnote = "Unavailable";
-		break;
-	case AST_EXTENSION_ONHOLD:
-		break;
-	case AST_EXTENSION_NOT_INUSE:
-	default:
-		/* Default setting */
-		break;
-	}
-
-	subscriptiontype = find_subscription_type(p->subscribed);
-	
-	/* Check which device/devices we are watching  and if they are registered */
-	if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
-		/* If they are not registered, we will override notification and show no availability */
-		if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
-			local_state = NOTIFY_CLOSED;
-			pidfstate = "away";
-			pidfnote = "Not online";
-		}
-	}
-
-	ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
-	c = get_in_brackets(from);
-	if (strncmp(c, "sip:", 4)) {
-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
-		return -1;
-	}
-	mfrom = strsep(&c, ";");	/* trim ; and beyond */
-
-	ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
-	c = get_in_brackets(to);
-	if (strncmp(c, "sip:", 4)) {
-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
-		return -1;
-	}
-	mto = strsep(&c, ";");	/* trim ; and beyond */
-
-	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
-
-	
-	add_header(&req, "Event", subscriptiontype->event);
-	add_header(&req, "Content-Type", subscriptiontype->mediatype);
-	switch(state) {
-	case AST_EXTENSION_DEACTIVATED:
-		if (timeout)
-			add_header(&req, "Subscription-State", "terminated;reason=timeout");
-		else {
-			add_header(&req, "Subscription-State", "terminated;reason=probation");
-			add_header(&req, "Retry-After", "60");
-		}
-		break;
-	case AST_EXTENSION_REMOVED:
-		add_header(&req, "Subscription-State", "terminated;reason=noresource");
-		break;
-	default:
-		if (p->expiry)
-			add_header(&req, "Subscription-State", "active");
-		else	/* Expired */
-			add_header(&req, "Subscription-State", "terminated;reason=timeout");
-	}
-	switch (p->subscribed) {
-	case XPIDF_XML:
-	case CPIM_PIDF_XML:
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-		ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
-		ast_build_string(&t, &maxbytes, "<presence>\n");
-		ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
-		ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
-		ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
-		ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
-		ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
-		ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
-		break;
-	case PIDF_XML: /* Eyebeam supports this format */
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
-		ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
-		ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
-		if (pidfstate[0] != '-')
-			ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
-		ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
-		ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
-		ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
-		ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
-		if (pidfstate[0] == 'b') /* Busy? Still open ... */
-			ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
-		else
-			ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
-		ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
-		break;
-	case DIALOG_INFO_XML: /* SNOM subscribes in this format */
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-		ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
-		if ((state & AST_EXTENSION_RINGING) && global.notifyringing)
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
-		else
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
-		ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
-		ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
-		break;
-	case NONE:
-	default:
-		break;
-	}
-
-	if (t > tmp + sizeof(tmp))
-		ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
-
-	add_header_contentLength(&req, strlen(tmp));
-	add_line(&req, tmp);
-
-	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
-}
-
 /*! \brief Notify user of messages waiting in voicemail
 \note	- Notification only works for registered peers with mailbox= definitions
 	in sip.conf
@@ -2629,30 +2458,6 @@
 	if (!p->initreq.headers) 	/* Initialize first request before sending */
 		initialize_initreq(p, req);
 	return send_request(p, req, XMIT_UNRELIABLE, p->ocseq);
-}
-
-/*! \brief Notify a transferring party of the status of transfer */
-GNURK int transmit_notify_with_sipfrag(struct sip_dialog *p, int cseq, char *message, int terminate)
-{
-	struct sip_request req;
-	char tmp[BUFSIZ/2];
-
-	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
-	snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
-	add_header(&req, "Event", tmp);
-	add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
-	add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
-	add_header(&req, "Allow", ALLOWED_METHODS);
-	add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
-
-	snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
-	add_header_contentLength(&req, strlen(tmp));
-	add_line(&req, tmp);
-
-	if (!p->initreq.headers)
-		initialize_initreq(p, &req);
-
-	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
 
 /*! \brief Transmit text with SIP MESSAGE method */
@@ -2839,16 +2644,6 @@
 		ASTOBJ_UNREF(peer, sip_destroy_device);		/* Remove from memory */
 	}
 
-	return 0;
-}
-
-/*! \brief Poke peer (send qualify to check if peer is alive and well) */
-static int sip_poke_peer_s(void *data)
-{
-	struct sip_peer *peer = data;
-
-	peer->pokeexpire = -1;
-	sip_poke_peer(peer);
 	return 0;
 }
 
@@ -4834,55 +4629,6 @@
 	}
 }
 
-
-/*! \brief Handle qualification responses (OPTIONS) */
-static void handle_response_peerpoke(struct sip_dialog *p, int resp, struct sip_request *req)
-{
-	struct sip_peer *peer = p->relatedpeer;
-	int statechanged, is_reachable, was_reachable;
-	int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
-
-	/*
-	 * Compute the response time to a ping (goes in peer->lastms.)
-	 * -1 means did not respond, 0 means unknown,
-	 * 1..maxms is a valid response, >maxms means late response.
-	 */
-	if (pingtime < 1)	/* zero = unknown, so round up to 1 */
-		pingtime = 1;
-
-	/* Now determine new state and whether it has changed.
-	 * Use some helper variables to simplify the writing
-	 * of the expressions.
-	 */
-	was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
-	is_reachable = pingtime <= peer->maxms;
-	statechanged = peer->lastms == 0 /* yes, unknown before */
-		|| was_reachable != is_reachable;
-
-	peer->lastms = pingtime;
-	peer->call = NULL;
-	if (statechanged) {
-		const char *s = is_reachable ? "Reachable" : "Lagged";
-
-		ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
-			peer->name, s, pingtime, peer->maxms);
-		ast_device_state_changed("SIP/%s", peer->name);
-		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
-			"Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
-			peer->name, s, pingtime);
-	}
-
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
-
-	/* Try again eventually */
-	peer->pokeexpire = ast_sched_add(sched,
-		is_reachable ? global.default_qualifycheck_ok: global.default_qualifycheck_notok,
-		sip_poke_peer_s, peer);
-
-	dialogstatechange(p, DIALOG_STATE_TERMINATED);
-	ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
-}
 
 /*! \brief Handle SIP response in dialogue */
 /* XXX only called by handle_request */
@@ -6845,87 +6591,6 @@
 	return 0;
 }
 
-/*! \brief React to lack of answer to Qualify poke */
-static int sip_poke_noanswer(void *data)
-{
-	struct sip_peer *peer = data;
-	
-	peer->pokeexpire = -1;
-	if (peer->lastms > -1) {
-		ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
-		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
-	}
-	if (peer->call)
-		sip_destroy(peer->call);
-	peer->call = NULL;
-	peer->lastms = -1;
-	ast_device_state_changed("SIP/%s", peer->name);
-	/* Try again quickly */
-	peer->pokeexpire = ast_sched_add(sched, global.default_qualifycheck_notok, sip_poke_peer_s, peer);
-	return 0;
-}
-
-/*! \brief Check availability of peer, also keep NAT open
-\note	This is done with the interval in qualify= configuration option
-	Default is 2 seconds */
-static int sip_poke_peer(struct sip_peer *peer)
-{
-	struct sip_dialog *p;
-
-	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 */
-		if (peer->pokeexpire > -1)
-			ast_sched_del(sched, peer->pokeexpire);
-		peer->lastms = 0;
-		peer->pokeexpire = -1;
-		peer->call = NULL;
-		return 0;
-	}
-	if (peer->call > 0) {
-		if (sipdebug)
-			ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
-		sip_destroy(peer->call);
-	}
-	if (!(p = peer->call = sip_alloc(NULL, NULL, FALSE, SIP_OPTIONS)))
-		return -1;
-	
-	p->sa = peer->addr;
-	p->recv = peer->addr;
-	ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
-	ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
-
-	/* Send OPTIONs to peer's fullcontact */
-	if (!ast_strlen_zero(peer->fullcontact))
-		ast_string_field_set(p, fullcontact, peer->fullcontact);
-
-	if (!ast_strlen_zero(peer->tohost))
-		ast_string_field_set(p, tohost, peer->tohost);
-	else
-		ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
-
-	/* Recalculate our side, and recalculate Call ID */
-	if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
-		p->ourip = sipnet.__ourip;
-	build_via(p, FALSE);
-	build_callid_pvt(p);
-
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
-	p->relatedpeer = peer;
-	ast_set_flag(&p->flags[0], SIP_OUTGOING);
-#ifdef VOCAL_DATA_HACK
-	ast_copy_string(p->peername, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->peername));
-	transmit_invite(p, SIP_INVITE, FALSE, 2);
-#else
-	transmit_invite(p, SIP_OPTIONS, FALSE, 2);
-#endif
-	gettimeofday(&peer->ps, NULL);
-	peer->pokeexpire = ast_sched_add(sched, DEFAULT_QUALIFY_MAXMS * 2, sip_poke_noanswer, peer);
-
-	return 0;
-}
-
 /*! \brief Part of PBX channel interface
 \note
 \par	Return values:---
@@ -7340,28 +7005,6 @@
 	return -1;
 }
 
-/*! \brief 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?
-*/
-static void sip_poke_all_peers(void)
-{
-	int ms = 0;
-	
-	if (!sipcounters.static_peers)	/* No peers, just give up */
-		return;
-
-	ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do {
-		ASTOBJ_WRLOCK(iterator);
-		if (iterator->pokeexpire > -1)
-			ast_sched_del(sched, iterator->pokeexpire);
-		ms += 100;
-		iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
-		ASTOBJ_UNLOCK(iterator);
-	} while (0)
-	);
-}
-
 /*! \brief Reload module */
 GNURK int sip_do_reload(enum channelreloadreason reason)
 {

Modified: team/oej/codename-pineapple/channels/sip3/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/Makefile?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/Makefile (original)
+++ team/oej/codename-pineapple/channels/sip3/Makefile Tue Nov 14 15:27:21 2006
@@ -3,7 +3,7 @@
 #
 all: sip3_refer.o sip3_subscribe.o sip3_network.o sip3_domain.o sip3_callerid.o sip3_auth.o \
 	sip3_sdprtp.o sip3_config.o sip3_cliami.o sip3_dialog.o sip3_services.o \
-	sip3_compose.o sip3_parse.o sip3_utils.o
+	sip3_compose.o sip3_parse.o sip3_utils.o sip3_pokedevice.o
 
 %.o: %.c sip3funcs.h sip3.h
 	$(CC) $(CFLAGS) -c -o $@ $<

Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Tue Nov 14 15:27:21 2006
@@ -117,7 +117,6 @@
 /*! \brief A per-thread temporary pvt structure */
 AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup);
 
-
 /*! \brief Protect the SIP dialog list (of sip_dialog's) */
 AST_MUTEX_DEFINE_STATIC(dialoglock);
 
@@ -125,7 +124,7 @@
 void dialoglist_lock(void)
 {
 	ast_mutex_lock(&dialoglock);
-	if (option_debug > 3)
+	if (sipdebug && option_debug > 4)
 		ast_log(LOG_DEBUG, "=== SIP dialog list: LOCKED\n");
 }
 
@@ -133,7 +132,7 @@
 void dialoglist_unlock(void)
 {
 	ast_mutex_unlock(&dialoglock);
-	if (option_debug > 3)
+	if (sipdebug && option_debug > 4)
 		ast_log(LOG_DEBUG, "=== SIP dialog list: UNLOCKED\n");
 }
 
@@ -142,6 +141,13 @@
 */
 void dialog_lock(struct sip_dialog *dialog, int state)
 {
+	if (!dialog) {
+		ast_log(LOG_ERROR, "-DIALOGLOCK- Trying to %s non-existing dialog. Giving up.\n", state ? "lock" : "unlock");
+		return;
+	}
+	if (sipdebug && option_debug > 4)
+		ast_log(LOG_DEBUG, "-DIALOGLOCK- %s dialog %s\n", state ? "  locking" : "unlocking", dialog->callid ? dialog->callid : "<no callid>");
+
 	if (state)
 		ast_mutex_lock(&dialog->lock);
 	else
@@ -198,12 +204,15 @@
 
 /*! \brief Transmit final response to a request and close dialog 
 	Set dialog state to TERMINATED to avoid problems
+	At some point, after debugging, we can remove the reliable flag. Only responses to INVITEs are sent reliably 
  */
 int transmit_final_response(struct sip_dialog *dialog, const char *msg, const struct sip_request *req, enum xmittype reliable)
 {
 	int res;
 
 	/* If this is a final response to an INVITE */
+	if (reliable == XMIT_RELIABLE && req->method != SIP_INVITE)
+		ast_log(LOG_WARNING, "Transmitting RELIABLE response to %s - Call ID %s (?? BUG ?? ) \n", sip_method2txt(req->method), dialog->callid);
 	res = __transmit_response(dialog, msg, req, reliable);
 	sip_scheddestroy(dialog, -1);	/* Destroy by using T1 timer if available */
 	dialogstatechange(dialog, DIALOG_STATE_TERMINATED);
@@ -253,7 +262,7 @@
 }
 
 /*! \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 */
+ *   maybe the lock on p is not strictly necessary but there might be a race */
 GNURK void __sip_pretend_ack(struct sip_dialog *dialog)
 {
 	struct sip_request *cur = NULL;
@@ -302,6 +311,11 @@
 {
 	struct sip_dialog *cur, *prev = NULL;
 	struct sip_request *cp;
+
+	if (ast_test_flag(&dialog->flags[0], SIP_INC_COUNT)) 			/* This dialog has incremented call count */
+		update_call_counter(dialog, DEC_CALL_LIMIT);				/* Since it was forgotten, decrement call count */
+	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_INC_RINGING)) 			/* This dialog has incremented ring count */
+		update_call_counter(dialog, DEC_CALL_RINGING);				/* Since it was forgotten, decrement ring count */
 
 	if (sip_debug_test_pvt(dialog) || option_debug > 2)
 		ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", dialog->callid, sip_method2txt(dialog->method));

Modified: team/oej/codename-pineapple/channels/sip3/sip3_parse.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_parse.c?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_parse.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_parse.c Tue Nov 14 15:27:21 2006
@@ -184,6 +184,13 @@
 /*! \brief return text string for sip method */
 char *sip_method2txt(int method)
 {
+	int max = sizeof(sip_methods) / sizeof(sip_methods[0]);
+
+	if (method > max || method < 0) {
+		if (option_debug > 3)
+			ast_log(LOG_DEBUG, "Unknown SIP method %d given to this function. Strange... \n", method);
+		return "<unknown>";
+	}
 	return sip_methods[method].text;
 }
 

Added: team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c?view=auto&rev=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c (added)
+++ team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c Tue Nov 14 15:27:21 2006
@@ -1,0 +1,255 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions)
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief SIP qualification subsystem - poking around on the network
+ * Version 3 of chan_sip
+ *
+ * \author Mark Spencer <markster at digium.com>
+ * \author Olle E. Johansson <oej at edvina.net> (all the chan_sip3 changes)
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ *
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <regex.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/config.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"
+#include "asterisk/options.h"
+#include "asterisk/lock.h"
+#include "asterisk/sched.h"
+#include "asterisk/io.h"
+#include "asterisk/rtp.h"
+#include "asterisk/udptl.h"
+#include "asterisk/acl.h"
+#include "asterisk/manager.h"
+#include "asterisk/callerid.h"
+#include "asterisk/cli.h"
+#include "asterisk/app.h"
+#include "asterisk/musiconhold.h"
+#include "asterisk/dsp.h"
+#include "asterisk/features.h"
+#include "asterisk/acl.h"
+#include "asterisk/srv.h"
+#include "asterisk/astdb.h"
+#include "asterisk/causes.h"
+#include "asterisk/utils.h"
+#include "asterisk/file.h"
+#include "asterisk/astobj.h"
+#include "asterisk/dnsmgr.h"
+#include "asterisk/devicestate.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/monitor.h"
+#include "asterisk/localtime.h"
+#include "asterisk/abstract_jb.h"
+#include "asterisk/compiler.h"
+#include "sip3.h"
+#include "sip3funcs.h"
+
+/*! \brief Poke peer (send qualify to check if peer is alive and well) */
+int sip_poke_peer_s(void *data)
+{
+	struct sip_peer *peer = data;
+
+	peer->pokeexpire = -1;
+	sip_poke_peer(peer);
+	return 0;
+}
+
+/*! \brief Handle qualification responses (OPTIONS) */
+void handle_response_peerpoke(struct sip_dialog *p, int resp, struct sip_request *req)
+{
+	struct sip_peer *peer = p->relatedpeer;
+	int statechanged, is_reachable, was_reachable;
+	int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
+
+	/*
+	 * Compute the response time to a ping (goes in peer->lastms.)
+	 * -1 means did not respond, 0 means unknown,
+	 * 1..maxms is a valid response, >maxms means late response.
+	 */
+	if (pingtime < 1)	/* zero = unknown, so round up to 1 */
+		pingtime = 1;
+
+	/* Now determine new state and whether it has changed.
+	 * Use some helper variables to simplify the writing
+	 * of the expressions.
+	 */
+	was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
+	is_reachable = pingtime <= peer->maxms;
+	statechanged = peer->lastms == 0 /* yes, unknown before */
+		|| was_reachable != is_reachable;
+
+	peer->lastms = pingtime;
+	peer->call = NULL;
+	if (statechanged) {
+		const char *s = is_reachable ? "Reachable" : "Lagged";
+
+		ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
+			peer->name, s, pingtime, peer->maxms);
+		ast_device_state_changed("SIP/%s", peer->name);
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
+			"Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
+			peer->name, s, pingtime);
+	}
+
+	if (peer->pokeexpire > -1)
+		ast_sched_del(sched, peer->pokeexpire);
+
+	/* Try again eventually */
+	peer->pokeexpire = ast_sched_add(sched,
+		is_reachable ? global.default_qualifycheck_ok: global.default_qualifycheck_notok,
+		sip_poke_peer_s, peer);
+
+	dialogstatechange(p, DIALOG_STATE_TERMINATED);
+	ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
+}
+
+/*! \brief React to lack of answer to Qualify poke */
+int sip_poke_noanswer(void *data)
+{
+	struct sip_peer *peer = data;
+	
+	peer->pokeexpire = -1;
+	if (peer->lastms > -1) {
+		ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
+		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
+	}
+	if (peer->call)
+		sip_destroy(peer->call);
+	peer->call = NULL;
+	peer->lastms = -1;
+	ast_device_state_changed("SIP/%s", peer->name);
+	/* Try again quickly */
+	peer->pokeexpire = ast_sched_add(sched, global.default_qualifycheck_notok, sip_poke_peer_s, peer);
+	return 0;
+}
+
+/*! \brief Check availability of peer, also keep NAT open
+\note	This is done with the interval in qualify= configuration option
+	Default is 2 seconds */
+int sip_poke_peer(struct sip_peer *peer)
+{
+	struct sip_dialog *p;
+
+	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 */
+		if (peer->pokeexpire > -1)
+			ast_sched_del(sched, peer->pokeexpire);
+		peer->lastms = 0;
+		peer->pokeexpire = -1;
+		peer->call = NULL;
+		return 0;
+	}
+	if (peer->call > 0) {
+		if (sipdebug)
+			ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
+		sip_destroy(peer->call);
+	}
+	if (!(p = peer->call = sip_alloc(NULL, NULL, FALSE, SIP_OPTIONS)))
+		return -1;
+	
+	p->sa = peer->addr;
+	p->recv = peer->addr;
+	ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
+	ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
+
+	/* Send OPTIONs to peer's fullcontact */
+	if (!ast_strlen_zero(peer->fullcontact))
+		ast_string_field_set(p, fullcontact, peer->fullcontact);
+
+	if (!ast_strlen_zero(peer->tohost))
+		ast_string_field_set(p, tohost, peer->tohost);
+	else
+		ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
+
+	/* Recalculate our side, and recalculate Call ID */
+	if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		p->ourip = sipnet.__ourip;
+	build_via(p, FALSE);
+	build_callid_pvt(p);
+
+	if (peer->pokeexpire > -1)
+		ast_sched_del(sched, peer->pokeexpire);
+	p->relatedpeer = peer;
+	ast_set_flag(&p->flags[0], SIP_OUTGOING);
+#ifdef VOCAL_DATA_HACK
+	ast_copy_string(p->peername, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->peername));
+	transmit_invite(p, SIP_INVITE, FALSE, 2);
+#else
+	transmit_invite(p, SIP_OPTIONS, FALSE, 2);
+#endif
+	gettimeofday(&peer->ps, NULL);
+	peer->pokeexpire = ast_sched_add(sched, DEFAULT_QUALIFY_MAXMS * 2, sip_poke_noanswer, peer);
+
+	return 0;
+}
+
+/*! \brief 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?
+*/
+void sip_poke_all_peers(void)
+{
+	int ms = 0;
+	
+	if (!sipcounters.static_peers)	/* No peers, just give up */
+		return;
+
+	ASTOBJ_CONTAINER_TRAVERSE(&devicelist, 1, do {
+		ASTOBJ_WRLOCK(iterator);
+		if (iterator->pokeexpire > -1)
+			ast_sched_del(sched, iterator->pokeexpire);
+		ms += 100;
+		iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
+		ASTOBJ_UNLOCK(iterator);
+	} while (0)
+	);
+}
+

Propchange: team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/oej/codename-pineapple/channels/sip3/sip3_pokedevice.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/oej/codename-pineapple/channels/sip3/sip3_refer.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_refer.c?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_refer.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_refer.c Tue Nov 14 15:27:21 2006
@@ -978,3 +978,26 @@
 	return res;
 }
 
+/*! \brief Notify a transferring party of the status of transfer */
+GNURK int transmit_notify_with_sipfrag(struct sip_dialog *p, int cseq, char *message, int terminate)
+{
+	struct sip_request req;
+	char tmp[BUFSIZ/2];
+
+	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
+	snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
+	add_header(&req, "Event", tmp);
+	add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
+	add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
+	add_header(&req, "Allow", ALLOWED_METHODS);
+	add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+
+	snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
+	add_header_contentLength(&req, strlen(tmp));
+	add_line(&req, tmp);
+
+	if (!p->initreq.headers)
+		initialize_initreq(p, &req);
+
+	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
+}

Modified: team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c?view=diff&rev=47624&r1=47623&r2=47624
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_subscribe.c Tue Nov 14 15:27:21 2006
@@ -129,3 +129,165 @@
 	}
 	return &subscription_types[0];
 }
+
+/*! \brief Used in the SUBSCRIBE notification subsystem */
+GNURK int transmit_state_notify(struct sip_dialog *p, int state, int full, int timeout)
+{
+	char tmp[4000], from[256], to[256];
+	char *t = tmp, *c, *mfrom, *mto;
+	size_t maxbytes = sizeof(tmp);
+	struct sip_request req;
+	char hint[AST_MAX_EXTENSION];
+	char *statestring = "terminated";
+	const struct cfsubscription_types *subscriptiontype;
+	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
+	char *pidfstate = "--";
+	char *pidfnote= "Ready";
+
+	memset(from, 0, sizeof(from));
+	memset(to, 0, sizeof(to));
+	memset(tmp, 0, sizeof(tmp));
+
+	switch (state) {
+	case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
+		statestring = (global.notifyringing) ? "early" : "confirmed";
+		local_state = NOTIFY_INUSE;
+		pidfstate = "busy";
+		pidfnote = "Ringing";
+		break;
+	case AST_EXTENSION_RINGING:
+		statestring = "early";
+		local_state = NOTIFY_INUSE;
+		pidfstate = "busy";
+		pidfnote = "Ringing";
+		break;
+	case AST_EXTENSION_INUSE:
+		statestring = "confirmed";
+		local_state = NOTIFY_INUSE;
+		pidfstate = "busy";
+		pidfnote = "On the phone";
+		break;
+	case AST_EXTENSION_BUSY:
+		statestring = "confirmed";
+		local_state = NOTIFY_CLOSED;
+		pidfstate = "busy";
+		pidfnote = "On the phone";
+		break;
+	case AST_EXTENSION_UNAVAILABLE:
+		statestring = "confirmed";
+		local_state = NOTIFY_CLOSED;
+		pidfstate = "away";
+		pidfnote = "Unavailable";
+		break;
+	case AST_EXTENSION_ONHOLD:
+		break;
+	case AST_EXTENSION_NOT_INUSE:
+	default:
+		/* Default setting */
+		break;
+	}
+
+	subscriptiontype = find_subscription_type(p->subscribed);
+	
+	/* Check which device/devices we are watching  and if they are registered */
+	if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
+		/* If they are not registered, we will override notification and show no availability */
+		if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
+			local_state = NOTIFY_CLOSED;
+			pidfstate = "away";
+			pidfnote = "Not online";
+		}
+	}
+
+	ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
+	c = get_in_brackets(from);
+	if (strncmp(c, "sip:", 4)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
+		return -1;
+	}
+	mfrom = strsep(&c, ";");	/* trim ; and beyond */
+
+	ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
+	c = get_in_brackets(to);
+	if (strncmp(c, "sip:", 4)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
+		return -1;
+	}
+	mto = strsep(&c, ";");	/* trim ; and beyond */
+
+	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
+
+	
+	add_header(&req, "Event", subscriptiontype->event);
+	add_header(&req, "Content-Type", subscriptiontype->mediatype);
+	switch(state) {
+	case AST_EXTENSION_DEACTIVATED:
+		if (timeout)
+			add_header(&req, "Subscription-State", "terminated;reason=timeout");
+		else {
+			add_header(&req, "Subscription-State", "terminated;reason=probation");
+			add_header(&req, "Retry-After", "60");
+		}
+		break;
+	case AST_EXTENSION_REMOVED:
+		add_header(&req, "Subscription-State", "terminated;reason=noresource");
+		break;
+	default:
+		if (p->expiry)
+			add_header(&req, "Subscription-State", "active");
+		else	/* Expired */
+			add_header(&req, "Subscription-State", "terminated;reason=timeout");
+	}
+	switch (p->subscribed) {
+	case XPIDF_XML:
+	case CPIM_PIDF_XML:
+		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
+		ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
+		ast_build_string(&t, &maxbytes, "<presence>\n");
+		ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
+		ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
+		ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
+		ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
+		ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
+		ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
+		break;
+	case PIDF_XML: /* Eyebeam supports this format */
+		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
+		ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
+		ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
+		if (pidfstate[0] != '-')
+			ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
+		ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
+		ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
+		ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
+		ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
+		if (pidfstate[0] == 'b') /* Busy? Still open ... */
+			ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
+		else

[... 97 lines stripped ...]


More information about the svn-commits mailing list