Current status of the ppcgui branch

Athanasios Karapantelakis athkar at kth.se
Mon Nov 13 15:53:31 CET 2006


Hello,

   There have been some developments with the pocket pc version (namely 
ppcgui branch), and trying to run minisip properly, initially as a 
console application, using a third-party console emulator [1].

   The first problem was that the text output on the console, namely the 
char * return type widely use from error/debug reporting functions as 
well as from textui itself, does not apply in Windows CE, which uses 
UNICODE instead of ASCII [2]. In order to solve this problem, a new 
universal library was created ("libmconsole"), which accepts a char* 
input, and converts it accordingly to wchar_t, if the architecture is 
windows ce, or simply outputs the char* text otherwise. Furthermore this 
library has the option to send the output text encapsulated in UDP 
packets, so debugging would be more convenient in the future GUI, where 
no text output is available. Another thing observed is that of 
overlapping text, when multiple threads tried to output something to the 
console at the same time. Note that this was common both for the windows 
version of minisip, and the pocket pc version. libmconsole encapsulates 
the output function in a critical region, so that one thread can output 
text each time. Attached is the wceconsole.cpp file featuring the 
functionality mentioned above.

  Another problem for Windows ce is that there is no windns library 
available, so it is not possible to resolve the ip address of a domain 
name (at least with the code we found on the trunk). The function 
responsible for resolving domain names to ip addresses is called 
getHostHandlingService, located in NetworkFunctions.cxx, and for windows 
CE, it just returns the domain string, without doing any effort to 
resolve it to an IP address. Naturally, this will work only if the 
address of the registrar is an IP address and not a canonical name. If 
there is any omission here, or this functionality is already implemented 
elsewhere, feedback is most appreciated.

   The problems the project faces at the moment concern thread 
synchronization, and seem to be related to the function 
WaitForSingleObject. As I understand it, this function is called 
whenever the program waits for another thread to finish a task, and in 
the meantime it goes into sleep mode, consuming a small amount of 
resources (critical for this platform). However, if used with the 
INFINITE handle (wait forever, without a timeout), the current thread 
can wait forever, until another thread finishes its task, and this is 
observed in the following cases (examples with partial call stacks):

   When placing a call, at some point the program has to construct the 
sip stack for an invite message:

Sip.cxx [minisip] ->
addDialog sipdialogcontainer.cxx  [libmsip] ->
addDialog sipmessagedispatcher.cxx  [libmsip] - dialogListLock.lock(); ->
Mutex::lock  [libmutil] - 
WaitForSingleObject(*((HANDLE*)handle_ptr),INFINITE);

   When shutting down the programm, the sip stack thread must exit, but 
it never does:

minisip.cxx "sip->join()" minisip::exit  [minisip] ->
sip.cxx "thread->join()  [minisip] ->
thread.cxx thread::join()  [libmutil]

   Upon removing the WaitForSingleObject from lock and join functions, 
the program does not get stuck, but behaves erratically:

- When calling an INVITE goes out but a reply (e.g. OK or CANCEL) is not 
sent back, when hanging up a CANCEL is sent, but still no reply is received.
- In the case of an incoming call the program informs the user of an 
incoming call from a (properly resolved) SIP uri but it cannot 
initialize the RTP stack.

   This springs some suspicions about whether the thread model in 
Windows behaves similarly in Windows CE (note that the same code 
compiles & runs successfully on windows - using the visual studio 
compiler), perhaps setting a timeout instead of INFINITE would help in 
this case?
  
   Since the project files and many source files changed in order to 
support the new console library, uploading them using commit would again 
result in a large email.  Is there any way to do a copy with kdesvn ?

[1] http://www.symbolictools.de/public/pocketconsole/index.htm
[2] http://msdn2.microsoft.com/en-us/library/ms834193.aspx
-------------- next part --------------
#include "wceconsole.h"

#define IP_ADDR "130.237.15.248"

static CRITICAL_SECTION consoleMutex;

//void consoleOut (string inputString, CRITICAL_SECTION consoleOUT){
#ifdef  LIBMCONSOLE_EXPORTS
	LIBMCONSOLE_API void consoleOut (char* inputString){
#else
	void consoleOut (char* inputString){
#endif

	#ifdef _WIN32_WCE // UDP sent packet section

	static int socketIsOpen = 0;	
	static SOCKET s;
	static SOCKADDR_IN targetDevice;
	EnterCriticalSection(&consoleMutex);
	if (socketIsOpen == 0){
		
		#ifdef _WIN32_WCE
			InitializeCriticalSection(&consoleMutex); //put this where init. is done
		#endif	
		socketIsOpen = 1;
		s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); //open socket

		if (s == INVALID_SOCKET) {
			int serror = WSAGetLastError();
			wprintf(L"wceconsole: socket error :%d\n", serror);
		}
	
		memset (&targetDevice, 0, sizeof(SOCKADDR_IN));

		targetDevice.sin_family = AF_INET;
		targetDevice.sin_port = htons(60);
		targetDevice.sin_addr.S_un.S_addr = inet_addr(IP_ADDR);
	}
	
	sendto(s, inputString, strlen(inputString), 0, (SOCKADDR *) &targetDevice, sizeof (SOCKADDR_IN));
	#endif
	
	const char *consoleOutTemp = inputString;

	#ifdef _WCE_ARCH
			wchar_t buffer [256];

			mbstowcs(buffer,  inputString, 256 );

			wprintf(L"%s", buffer);
	#elif defined _OTHER_ARCH
		printf("%s", consoleOutTemp);
		break;
	#else // Shouln't go here, nevertheless the structure is maintained for future architectures
		;
	#endif

	consoleOutTemp = NULL;
	LeaveCriticalSection(&consoleMutex);
	int i = 0;
	for (i = 1000000; i > 0; i--);

}

void consoleOutCleanup(){
	#ifdef _WIN32_WCE
		DeleteCriticalSection(&consoleMutex); //do this in cleanup 
	#endif	
		// TODO: socket cleanup
}


More information about the Minisip-devel mailing list