#13795: Initial commit for sflphone-android

includes: libexpat libyaml libdbus-c++ commoncpp ccrtp
          libdbus (from android-4.0.4 sources)

TODO:
- git ignores "/jni/sflphone", sflphone repo should be cloned.
- sflphone-android only needs daemon directory. Ideally it should be possible
to clone it without cloning the whole sflphone project.
into sfl-android (commit 6a0fa7a "#13961: Fix cipher handling" has been used here)
- add pjsip-android project as a git submodule
- sflphone-android needs pjsip android project. Ideally daemon git repository
should not embed pjsip. Instead pjsip should be clone from official repositories.

Considering this, structure should have three distincts git repos:

sflphone-android/.git
sflphone-android/jni/ccrtp-1.8.0-android
sflphone-android/jni/commoncpp2-1.8.1-android
sflphone-android/jni/dbus
sflphone-android/jni/libdbus-c++-0.9.0-android
sflphone-android/jni/libexpat
sflphone-android/jni/libyaml

sflphone-android/jni/sflphone-daemon/.git
sflphone-android/jni/sflphone-daemon/src/audio
sflphone-android/jni/sflphone-daemon/src/config
sflphone-android/jni/sflphone-daemon/src/dbus
sflphone-android/jni/sflphone-daemon/src/history
sflphone-android/jni/sflphone-daemon/src/hooks
sflphone-android/jni/sflphone-daemon/src/iax
sflphone-android/jni/sflphone-daemon/src/sip
sflphone-android/jni/sflphone-daemon/src/video

sflphone-android/jni/pjsip-android/.git

Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
diff --git a/jni/commoncpp2-1.8.1-android/demo/tcpservice.cpp b/jni/commoncpp2-1.8.1-android/demo/tcpservice.cpp
new file mode 100644
index 0000000..8e16a04
--- /dev/null
+++ b/jni/commoncpp2-1.8.1-android/demo/tcpservice.cpp
@@ -0,0 +1,413 @@
+//
+// tcpservice.cpp
+//
+//  Copyright 2000 - Gianni Mariani <gianni@mariani.ws>
+//
+//  An example of a simple chatty server using CommonC++.
+//
+//  This simple application basically operates as a
+//  very simple chat system. From a telnet session
+//  on localhost:3999 , any messages typed from a telnet
+//  client are written to all participating sessions.
+//
+//  This is free software licensed under the terms of the GNU
+//  Public License
+//
+//  This example:
+//
+//  This demostrates a simple threaded server, actually,
+//  the sessions are not all threaded though they could be
+//  if that's what you wanted.	Basically it demonstrates the
+//  use of SocketService, SocketPorts and Threads.
+//
+//  For those familiar with Unix network programming, SocketService
+//  basically encapsulates all the work to communicate with
+//  the select() or poll() system calls.  SocketPorts are
+//  basically encapsulations of sessions or open file descriptors.
+//
+//  Anyhow, this example is a very simple echo server but
+//  it echos to all connected clients.	So it's a poor man's
+//  IRC !  You connect via telnet to localhost port 3999 and
+//  it will echo to all other connected clients what you type in !
+//
+
+#include <cc++/socketport.h>
+
+#include <iostream>
+
+// For starters, we need a thread safe list, we'll make one
+// out of the STL list<> template -
+//  http://www.sgi.com/Technology/STL/index.html
+//
+// Thread safe list class
+//
+#include <list>
+
+#ifdef	CCXX_NAMESPACES
+using namespace std;
+using namespace ost;
+#endif
+
+class ts_list_item;
+typedef list<ts_list_item *> ts_list;
+
+// a list head - containing a list and a Mutex.
+// It would be really nice to teach stl to do this.
+
+class ts_list_head {
+public:
+
+	// No point inheriting, I'd have to implement
+	// alot of code. We'll hold off on that exercise.
+
+	// Using the CommonC++ Mutex class.
+	Mutex		    linkmutex;
+	// And the STL template.
+	ts_list		    list_o_items;
+
+	// Not nessasary, but nice to be explicit.
+	ts_list_head()
+	: linkmutex(), list_o_items() {
+	}
+
+	// This thing knows how to remove and insert items.
+	void RemoveListItem( ts_list_item * li );
+	void InsertListItem( ts_list_item * li );
+
+	// And it knows how to notify that it became empty
+	// or an element was deleted and it was the last one.
+	virtual void ListDepleted() {
+	}
+
+	virtual ~ts_list_head() {
+	}
+};
+
+
+// This item knows how to remove itself from the
+// list it belongs to.
+class ts_list_item {
+public:
+	ts_list::iterator	   linkpoint;
+	ts_list_head	  * listhead;
+
+	virtual ~ts_list_item() {
+	listhead->RemoveListItem( this );
+	}
+
+	ts_list_item( ts_list_head * head ) {
+	listhead = head;
+	head->InsertListItem( this );
+	}
+};
+
+void ts_list_head::RemoveListItem( ts_list_item * li )
+{
+	bool    is_empty;
+	linkmutex.enterMutex();
+	list_o_items.erase( li->linkpoint );
+	is_empty = list_o_items.empty();
+	linkmutex.leaveMutex();
+
+	// There is a slim possibility that at this time
+	// we recieve a connection.
+	if ( is_empty ) {
+	ListDepleted();
+	}
+}
+
+void ts_list_head::InsertListItem( ts_list_item * li )
+{
+	linkmutex.enterMutex();
+	list_o_items.push_front( li );
+	li->linkpoint = list_o_items.begin();
+	linkmutex.leaveMutex();
+}
+
+// ChatterSession operates on the individual connections
+// from clients as are managed by the SocketService
+// contained in CCExec.  ChatterThread simply waits in
+// a loop to create these, listening forever.
+//
+// Even though the SocketService contains a list of
+// clients it serves, it may actually serve more than
+// one type of session so we create our own list by
+// inheriting the ts_list_item.
+//
+
+class ChatterSession :
+	public virtual SocketPort,
+	public virtual ts_list_item {
+public:
+
+	enum { size_o_buf = 2048 };
+
+	// Nothing special to do here, it's all handled
+	// by SocketPort and ts_list_item
+
+	virtual ~ChatterSession() {
+	cerr << "ChatterSession deleted !\n";
+	}
+
+	// When you create a ChatterSession it waits to accept a
+	// connection.  This is done by it's own
+	ChatterSession(
+	TCPSocket      & server,
+	SocketService	* svc,
+	ts_list_head	* head
+	) :
+	SocketPort( NULL, server ),
+	ts_list_item( head ) {
+	cerr << "ChatterSession Created\n";
+
+	tpport_t port;
+	InetHostAddress ia = getPeer( & port );
+
+	cerr << "connecting from " << ia.getHostname() <<
+	":" << port << endl;
+
+	// Set up non-blocking reads
+	setCompletion( false );
+
+	// Set yerself to time out in 10 seconds
+	setTimer( 100000 );
+	attach(svc);
+	}
+
+	//
+	// This is called by the SocketService thread when it the
+	// object has expired.
+	//
+
+	virtual void expired() {
+	// Get outa here - this guy is a LOOSER - type or terminate
+	cerr << "ChatterSession Expired\n";
+	delete this;
+	}
+
+	//
+	// This is called by the SocketService thread when it detects
+	// that there is somthing to read on this connection.
+	//
+
+	virtual void pending() {
+	// Implement the echo
+
+	cerr << "Pending called\n";
+
+	// reset the timer
+	setTimer( 100000 );
+	try {
+	    int    len;
+	    unsigned int total = 0;
+	    char    buf[ size_o_buf ];
+
+	    while ( (len = receive(buf, sizeof(buf) )) > 0 ) {
+		total += len;
+		cerr << "Read '";
+		cerr.write( buf, len );
+		cerr << "'\n";
+
+		// Send it to all the sessions.
+		// We probably don't really want to lock the
+		// entire list for the entire time.
+		// The best way to do this would be to place the
+		// message somewhere and use the service function.
+		// But what are examples for ?
+
+		bool sent = false;
+		listhead->linkmutex.enterMutex();
+		for (
+		   ts_list::iterator iter = listhead->list_o_items.begin();
+		   iter != listhead->list_o_items.end();
+		   iter ++
+		) {
+		   ChatterSession * sess =
+		    dynamic_cast< ChatterSession * >( * iter );
+		   if ( sess != this ) {
+		    sess->send( buf, len );
+		    sent = true;
+		   }
+		}
+		listhead->linkmutex.leaveMutex();
+
+		if ( ! sent ) {
+		   send(
+		    ( void * ) "No one else listening\n",
+		    sizeof( "No one else listening\n" ) - 1
+		   );
+
+		   send( buf, len );
+		}
+	    }
+	    if (total == 0) {
+		cerr << "Broken connection!\n" << endl;
+		delete this;
+	    }
+	}
+	catch ( ... ) {
+	    // somthing wrong happened here !
+	    cerr << "Socket port write sent an exception !\n";
+	}
+
+	}
+
+	virtual void disconnect() {
+	// Called by the SocketService thread when the client
+	// hangs up.
+	cerr << "ChatterSession disconnected!\n";
+
+	delete this;
+	}
+
+};
+
+class ChatterThread;
+
+//
+// This is the main application object containing all the
+// state for the application.  It uses a SocketService object
+// (and thread) to do all the work, however, that object could
+// theoretically be use by more than one main application.
+//
+// It creates a ChatterThread to sit and wait for connections
+// from clients.
+
+class CCExec : public virtual ts_list_head {
+public:
+
+	SocketService	    * service;
+	ChatterThread	       * my_Chatter;
+	Semaphore		      mainsem[1];
+
+	CCExec():my_Chatter(NULL) {
+	service = new SocketService( 0 );
+	}
+
+	virtual void ListDepleted();
+
+	// These methods defined later.
+	virtual ~CCExec();
+	int RunApp( char * hn = (char *)"localhost" );
+
+};
+
+//
+// ChatterThread simply creates ChatterSession all the time until
+// it has an error.  I suspect you could create as many of these
+// as the OS could take.
+//
+
+class ChatterThread : public virtual TCPSocket, public virtual Thread {
+public:
+
+	CCExec		* exec;
+
+	void run () {
+	while ( 1 ) {
+	    try {
+		// new does all the work to accept a new connection
+		// attach itself to the SocketService AND include
+		// itself in the CCExec list of sessions.
+		new ChatterSession(
+		   * ( TCPSocket * ) this,
+		   exec->service,
+		   exec
+		);
+	    }
+	    catch ( ... ) {
+		// Bummer - there was an error.
+		cerr << "ChatterSession create failed\n";
+		exit();
+	    }
+	}
+	}
+
+	ChatterThread(
+	InetHostAddress & machine,
+	int	      port,
+	CCExec	       * inexec
+
+	) : TCPSocket( machine, port ),
+	Thread(),
+	exec( inexec ) {
+	    start();
+	}
+
+
+};
+
+//
+// Bug here, this should go ahead and shut down all sessions
+// for application.  An exercise left to the reader.
+
+CCExec::~CCExec()
+{
+	// MUST delete my_Chatter first or it may end up using
+	// a deleted service.
+	if ( my_Chatter ) delete my_Chatter;
+
+	// Delete whatever is left.
+	delete service;
+}
+
+//
+// Run App would normally read some config file or take some
+// parameters about which port to connect to and then
+// do that !
+int CCExec::RunApp( char * hn )
+{
+	// which port ?
+
+	InetHostAddress machine( hn );
+
+	if ( machine.isInetAddress() == false ) {
+	cerr << "machine is not address" << endl;
+	}
+
+	cerr << "machine is " << machine.getHostname() << endl;
+
+	// Start accepting connections - this will bind to the
+	// port as well.
+	try {
+	my_Chatter = new ChatterThread(
+	    machine,
+	    3999,
+	    this
+	);
+	}
+	catch ( ... ) {
+	cerr << "Failed to bind\n";
+	return false;
+	}
+
+	return true;
+}
+
+// When there is no one else connected - terminate !
+void CCExec::ListDepleted()
+{
+	mainsem->post();
+}
+
+
+int main( int argc, char ** argv )
+{
+	CCExec	* server;
+
+	server = new CCExec();
+
+	// take the first command line option as a hostname
+	// to listen to.
+	if ( argc > 1 ) {
+		server->RunApp( argv[ 1 ] );
+	} else {
+		server->RunApp();
+	}
+
+	server->mainsem->wait();
+
+	delete server;
+
+	return 0;
+}