Index: pjproject/trunk/pjsip-apps/src/py_pjsua/py_pjsua.c
===================================================================
--- pjproject/trunk/pjsip-apps/src/py_pjsua/py_pjsua.c	(revision 915)
+++ pjproject/trunk/pjsip-apps/src/py_pjsua/py_pjsua.c	(revision 916)
@@ -27,4 +27,5 @@
 static PyObject* obj_reconfigure_logging;
 static PyObject* obj_logging_init;
+static long thread_id;
 
 /*
@@ -51,5 +52,10 @@
 static void cb_logging_init(int level, const char *data, pj_size_t len)
 {
-	
+    /* Ignore if this callback is called from alien thread context,
+     * or otherwise it will crash Python.
+     */
+    if (pj_thread_local_get(thread_id) == 0)
+	return;
+
     if (PyCallable_Check(obj_logging_init))
     {
@@ -176,5 +182,5 @@
  * The global callback object.
  */
-static callback_Object * obj_callback;
+static callback_Object * g_obj_callback;
 
 
@@ -185,7 +191,5 @@
 static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
 {
-
-	printf("on_call_state called\n");
-    if (PyCallable_Check(obj_callback->on_call_state))
+    if (PyCallable_Check(g_obj_callback->on_call_state))
     {	
         pjsip_event_Object * obj;
@@ -198,5 +202,5 @@
 		
         PyObject_CallFunctionObjArgs(
-            obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
+            g_obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
         );
 		
@@ -212,6 +216,5 @@
                                 pjsip_rx_data *rdata)
 {
-	printf("on_incoming_call called\n");
-    if (PyCallable_Check(obj_callback->on_incoming_call))
+    if (PyCallable_Check(g_obj_callback->on_incoming_call))
     {
 	pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *)
@@ -221,5 +224,5 @@
 
         PyObject_CallFunctionObjArgs(
-                obj_callback->on_incoming_call,
+                g_obj_callback->on_incoming_call,
 		Py_BuildValue("i",acc_id),
                 Py_BuildValue("i",call_id),
@@ -237,8 +240,7 @@
 static void cb_on_call_media_state(pjsua_call_id call_id)
 {
-	printf("on_call_media_state called\n");
-    if (PyCallable_Check(obj_callback->on_call_media_state))
-    {
-        PyObject_CallFunction(obj_callback->on_call_media_state,"i",call_id);
+    if (PyCallable_Check(g_obj_callback->on_call_media_state))
+    {
+        PyObject_CallFunction(g_obj_callback->on_call_media_state,"i",call_id);
     }
 }
@@ -255,9 +257,8 @@
     PyObject * ret;
     int cd;
-	printf("on_call_transfer_request called\n");
-    if (PyCallable_Check(obj_callback->on_call_transfer_request))
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
     {
         ret = PyObject_CallFunctionObjArgs(
-            obj_callback->on_call_transfer_request,
+            g_obj_callback->on_call_transfer_request,
 	    Py_BuildValue("i",call_id),
             PyString_FromStringAndSize(dst->ptr, dst->slen),
@@ -291,9 +292,8 @@
     PyObject * ret;
     int cnt;
-	printf("on_call_transfer_status called\n");
-    if (PyCallable_Check(obj_callback->on_call_transfer_status))
+    if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
     {
         ret = PyObject_CallFunctionObjArgs(
-            obj_callback->on_call_transfer_status,
+            g_obj_callback->on_call_transfer_status,
 	    Py_BuildValue("i",call_id),
 	    Py_BuildValue("i",status_code),
@@ -327,6 +327,5 @@
     PyObject * txt;
     int cd;
-	printf("on_call_replace_request called\n");
-    if (PyCallable_Check(obj_callback->on_call_replace_request))
+    if (PyCallable_Check(g_obj_callback->on_call_replace_request))
     {
         pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *)
@@ -336,5 +335,5 @@
 
         ret = PyObject_CallFunctionObjArgs(
-            obj_callback->on_call_replace_request,
+            g_obj_callback->on_call_replace_request,
 	    Py_BuildValue("i",call_id),
 	    obj,
@@ -364,9 +363,8 @@
 				pjsua_call_id new_call_id)
 {
-	printf("on_call_replaced\n");
-    if (PyCallable_Check(obj_callback->on_call_replaced))
+    if (PyCallable_Check(g_obj_callback->on_call_replaced))
     {
         PyObject_CallFunctionObjArgs(
-            obj_callback->on_call_replaced,
+            g_obj_callback->on_call_replaced,
 	    Py_BuildValue("i",old_call_id),
 	    Py_BuildValue("i",old_call_id),
@@ -383,8 +381,7 @@
 static void cb_on_reg_state(pjsua_acc_id acc_id)
 {
-	printf("on_reg_state\n");
-    if (PyCallable_Check(obj_callback->on_reg_state))
-    {
-        PyObject_CallFunction(obj_callback->on_reg_state,"i",acc_id);
+    if (PyCallable_Check(g_obj_callback->on_reg_state))
+    {
+        PyObject_CallFunction(g_obj_callback->on_reg_state,"i",acc_id);
     }
 }
@@ -397,8 +394,7 @@
 static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
 {
-	printf("on_buddy_state called\n");
-    if (PyCallable_Check(obj_callback->on_buddy_state))
-    {
-        PyObject_CallFunction(obj_callback->on_buddy_state,"i",buddy_id);
+    if (PyCallable_Check(g_obj_callback->on_buddy_state))
+    {
+        PyObject_CallFunction(g_obj_callback->on_buddy_state,"i",buddy_id);
     }
 }
@@ -412,9 +408,8 @@
                         const pj_str_t *mime_type, const pj_str_t *body)
 {
-	printf("on_pager called\n");
-    if (PyCallable_Check(obj_callback->on_pager))
+    if (PyCallable_Check(g_obj_callback->on_pager))
     {
         PyObject_CallFunctionObjArgs(
-            obj_callback->on_pager,Py_BuildValue("i",call_id),
+            g_obj_callback->on_pager,Py_BuildValue("i",call_id),
             PyString_FromStringAndSize(from->ptr, from->slen),
             PyString_FromStringAndSize(to->ptr, to->slen),
@@ -438,9 +433,8 @@
 	
     PyObject * obj = PyType_GenericNew(user_data, NULL, NULL);
-	printf("on_pager_status called\n");
-    if (PyCallable_Check(obj_callback->on_pager))
+    if (PyCallable_Check(g_obj_callback->on_pager))
     {
         PyObject_CallFunctionObjArgs(
-            obj_callback->on_pager,Py_BuildValue("i",call_id),
+            g_obj_callback->on_pager,Py_BuildValue("i",call_id),
             PyString_FromStringAndSize(to->ptr, to->slen),
             PyString_FromStringAndSize(body->ptr, body->slen),obj,
@@ -460,9 +454,8 @@
                             pj_bool_t is_typing)
 {
-	printf("on_typing called\n");
-    if (PyCallable_Check(obj_callback->on_typing))
+    if (PyCallable_Check(g_obj_callback->on_typing))
     {
         PyObject_CallFunctionObjArgs(
-            obj_callback->on_typing,Py_BuildValue("i",call_id),
+            g_obj_callback->on_typing,Py_BuildValue("i",call_id),
             PyString_FromStringAndSize(from->ptr, from->slen),
             PyString_FromStringAndSize(to->ptr, to->slen),
@@ -1726,4 +1719,7 @@
 #endif
     status = pj_thread_register(name, thread_desc, &thread);
+
+    if (status == PJ_SUCCESS)
+	status = pj_thread_local_set(thread_id, (void*)1);
     return Py_BuildValue("i",status);
 }
@@ -1992,5 +1988,11 @@
     }
     status = pjsua_create();
-    //printf("status %d\n",status);
+    
+    if (status == PJ_SUCCESS) {
+	status = pj_thread_local_alloc(&thread_id);
+	if (status == PJ_SUCCESS)
+	    status = pj_thread_local_set(thread_id, (void*)1);
+    }
+
     return Py_BuildValue("i",status);
 }
@@ -2028,15 +2030,31 @@
 
     if (ua_cfgObj != Py_None) {
-		ua_cfg = (config_Object *)ua_cfgObj;
+	ua_cfg = (config_Object *)ua_cfgObj;
         cfg_ua.cred_count = ua_cfg->cred_count;
         for (i = 0; i < 4; i++)
-		{
+	{
             cfg_ua.cred_info[i] = ua_cfg->cred_info[i];
-		}
+	}
         cfg_ua.max_calls = ua_cfg->max_calls;
         for (i = 0; i < PJSUA_ACC_MAX_PROXIES; i++)
-		{
+	{
             cfg_ua.outbound_proxy[i] = ua_cfg->outbound_proxy[i];
-		}
+	}
+
+    	g_obj_callback = ua_cfg->cb;
+    	Py_INCREF(g_obj_callback);
+
+    	cfg_ua.cb.on_call_state = &cb_on_call_state;
+    	cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
+    	cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
+    	cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
+    	cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
+    	cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
+    	cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
+    	cfg_ua.cb.on_reg_state = &cb_on_reg_state;
+    	cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
+    	cfg_ua.cb.on_pager = &cb_on_pager;
+    	cfg_ua.cb.on_pager_status = &cb_on_pager_status;
+    	cfg_ua.cb.on_typing = &cb_on_typing;
 
         cfg_ua.outbound_proxy_cnt = ua_cfg->outbound_proxy_cnt;
@@ -2045,21 +2063,9 @@
         cfg_ua.user_agent.slen = strlen(cfg_ua.user_agent.ptr);
 
-        obj_callback = ua_cfg->cb;
-        cfg_ua.cb.on_call_state = &cb_on_call_state;
-        cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
-        cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
-        cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
-        cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
-        cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
-        cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
-        cfg_ua.cb.on_reg_state = &cb_on_reg_state;
-        cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
-        cfg_ua.cb.on_pager = &cb_on_pager;
-        cfg_ua.cb.on_pager_status = &cb_on_pager_status;
-        cfg_ua.cb.on_typing = &cb_on_typing;
         p_cfg_ua = &cfg_ua;
     } else {
         p_cfg_ua = NULL;
-	}
+    }
+
     if (log_cfgObj != Py_None) {
         log_cfg = (logging_config_Object *)log_cfgObj;
@@ -2077,5 +2083,6 @@
     } else {
         p_cfg_log = NULL;
-	}
+    }
+
     if (media_cfgObj != Py_None) {
         media_cfg = (media_config_Object *)media_cfgObj;
@@ -2093,7 +2100,8 @@
         cfg_media.tx_drop_pct = media_cfg->tx_drop_pct;
 	    p_cfg_media = &cfg_media;
-	} else {
+    } else {
         p_cfg_media = NULL;
-	}
+    }
+
     status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
     return Py_BuildValue("i",status);
@@ -3960,4 +3968,6 @@
         return NULL;
     }
+
+    pjsua_acc_config_default(&cfg);
     if (acObj != Py_None)
 	{
@@ -3965,5 +3975,5 @@
         cfg.cred_count = ac->cred_count;
         for (i = 0; i < 8; i++) 
-		{
+	{
             /*cfg.cred_info[i] = ac->cred_info[i];*/
 	        pjsip_cred_info_Object * ci = (pjsip_cred_info_Object *)
@@ -3980,5 +3990,5 @@
 				(PyString_AsString(ci->username));
 	        cfg.cred_info[i].data_type = ci->data_type;
-		}
+	}
         cfg.force_contact.ptr = PyString_AsString(ac->force_contact);
         cfg.force_contact.slen = strlen(PyString_AsString(ac->force_contact));
@@ -3990,5 +4000,5 @@
 	        cfg.proxy[i].ptr = PyString_AsString
 				(PyList_GetItem((PyObject *)ac->proxy,i));
-		}
+	}
         cfg.proxy_cnt = ac->proxy_cnt;
         cfg.publish_enabled = ac->publish_enabled;
@@ -7163,5 +7173,5 @@
     dst_uri.slen = strlen(PyString_AsString(sd));
     if (omdObj != Py_None) {
-		omd = (msg_data_Object *)omdObj;
+	omd = (msg_data_Object *)omdObj;
         msg_data.content_type.ptr = PyString_AsString(omd->content_type);
         msg_data.content_type.slen = strlen
@@ -7174,8 +7184,9 @@
 			options, &user_data, &msg_data, &call_id);	
         pj_pool_release(pool);
-	} else {
+    } else {
         status = pjsua_call_make_call(acc_id, &dst_uri, 
 			options, &user_data, NULL, &call_id);	
-	}
+    }
+
     return Py_BuildValue("ii",status, call_id);
 }
@@ -7254,5 +7265,4 @@
     call_info_Object * oi;
     pjsua_call_info info;
-    int i;
     
 
@@ -7268,13 +7278,17 @@
         oi = (call_info_Object *)call_info_new(&call_info_Type, NULL, NULL);
         oi->acc_id = info.acc_id;
-        for (i = 0; i < 128; i++)
-	{
-	    oi->buf_.call_id[i] = info.buf_.call_id[i];
-	    oi->buf_.last_status_text[i] = info.buf_.last_status_text[i];
-	    oi->buf_.local_contact[i] = info.buf_.local_contact[i];
-	    oi->buf_.local_info[i] = info.buf_.local_info[i];
-	    oi->buf_.remote_contact[i] = info.buf_.remote_contact[i];
-	    oi->buf_.remote_info[i] = info.buf_.remote_info[i];
-	}
+	pj_ansi_snprintf(oi->buf_.call_id, sizeof(oi->buf_.call_id),
+			 "%.*s", (int)info.call_id.slen, info.call_id.ptr);
+	pj_ansi_snprintf(oi->buf_.last_status_text, sizeof(oi->buf_.last_status_text),
+			 "%.*s", (int)info.last_status_text.slen, info.last_status_text.ptr);
+	pj_ansi_snprintf(oi->buf_.local_contact, sizeof(oi->buf_.local_contact),
+			 "%.*s", (int)info.local_contact.slen, info.local_contact.ptr);
+	pj_ansi_snprintf(oi->buf_.local_info, sizeof(oi->buf_.local_info),
+			 "%.*s", (int)info.local_info.slen, info.local_info.ptr);
+	pj_ansi_snprintf(oi->buf_.remote_contact, sizeof(oi->buf_.remote_contact),
+			 "%.*s", (int)info.remote_contact.slen, info.remote_contact.ptr);
+	pj_ansi_snprintf(oi->buf_.remote_info, sizeof(oi->buf_.remote_info),
+			 "%.*s", (int)info.remote_info.slen, info.remote_info.ptr);
+
         oi->call_id = PyString_FromStringAndSize(info.call_id.ptr, 
 	    info.call_id.slen);
@@ -7372,5 +7386,5 @@
         return NULL;
     }
-	
+
     reason.ptr = PyString_AsString(sr);
     reason.slen = strlen(PyString_AsString(sr));
@@ -7409,5 +7423,5 @@
 	PyObject * omdObj;
     msg_data_Object * omd;    
-    pj_pool_t * pool;
+    pj_pool_t * pool = NULL;
 
     if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
@@ -7429,7 +7443,7 @@
         status = pjsua_call_hangup(call_id, code, &reason, &msg_data);	
         pj_pool_release(pool);
-	} else {
+    } else {
         status = pjsua_call_hangup(call_id, code, &reason, NULL);	
-	}
+    }
     return Py_BuildValue("i",status);
 }
