Index: pjproject/trunk/pjmedia/build/pjmedia.dsp
===================================================================
--- pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 403)
+++ pjproject/trunk/pjmedia/build/pjmedia.dsp	(revision 404)
@@ -88,4 +88,8 @@
 # Begin Source File
 
+SOURCE=..\src\pjmedia\clock_thread.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\pjmedia\codec.c
 # End Source File
@@ -124,4 +128,8 @@
 # Begin Source File
 
+SOURCE=..\src\pjmedia\master_port.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\pjmedia\null_port.c
 # End Source File
@@ -133,11 +141,4 @@
 
 SOURCE=..\src\pjmedia\pasound.c
-
-!IF  "$(CFG)" == "pjmedia - Win32 Release"
-
-!ELSEIF  "$(CFG)" == "pjmedia - Win32 Debug"
-
-!ENDIF 
-
 # End Source File
 # Begin Source File
@@ -199,4 +200,8 @@
 # Begin Source File
 
+SOURCE=..\include\pjmedia\clock.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\include\pjmedia\codec.h
 # End Source File
@@ -232,4 +237,8 @@
 
 SOURCE=..\include\pjmedia\jbuf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\include\pjmedia\master_port.h
 # End Source File
 # Begin Source File
Index: pjproject/trunk/pjmedia/include/pjmedia.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia.h	(revision 403)
+++ pjproject/trunk/pjmedia/include/pjmedia.h	(revision 404)
@@ -26,4 +26,5 @@
 
 #include <pjmedia/types.h>
+#include <pjmedia/clock.h>
 #include <pjmedia/codec.h>
 #include <pjmedia/conference.h>
@@ -33,4 +34,5 @@
 #include <pjmedia/g711.h>
 #include <pjmedia/jbuf.h>
+#include <pjmedia/master_port.h>
 #include <pjmedia/null_port.h>
 #include <pjmedia/port.h>
Index: pjproject/trunk/pjmedia/include/pjmedia/clock.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/clock.h	(revision 404)
+++ pjproject/trunk/pjmedia/include/pjmedia/clock.h	(revision 404)
@@ -0,0 +1,143 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJMEDIA_CLOCK_H__
+#define __PJMEDIA_CLOCK_H__
+
+/**
+ * @file clock.h
+ * @brief Media clock.
+ */
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for media clock.
+ */
+typedef struct pjmedia_clock pjmedia_clock;
+
+
+enum pjmedia_clock_options
+{
+    PJMEDIA_CLOCK_NO_ASYNC  = 1,
+};
+
+/**
+ * Type of media clock callback.
+ *
+ * @param ts		    Current timestamp, in samples.
+ * @param user_data	    Application data that is passed when
+ *			    the clock was created.
+ */
+typedef void pjmedia_clock_callback(const pj_timestamp *ts,
+				    void *user_data);
+
+
+
+/**
+ * Create media clock.
+ *
+ * @param pool		    Pool to allocate memory.
+ * @param clock_rate	    Number of samples per second.
+ * @param samples_per_frame Number of samples per frame. This argument
+ *			    along with clock_rate, specifies the interval
+ *			    of each clock run (or clock ticks).
+ * @param options	    By default, the callback will be called 
+ *			    asynchronously (depending on the clock 
+ *			    implementation backend, a thread may be 
+ *			    created). If PJMEDIA_CLOCK_NO_ASYNC is set,
+ *			    application must poll the clock with 
+ *			    #pjmedia_clock_wait() to let the clock runs.
+ * @param cb		    Callback to be called for each clock tick.
+ * @param user_data	    User data, which will be passed to the callback.
+ * @param p_clock	    Pointer to receive the clock instance.
+ *
+ * @return		    PJ_SUCCESS on success, or the appropriate error
+ *			    code.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
+					   unsigned clock_rate,
+					   unsigned samples_per_frame,
+					   unsigned options,
+					   pjmedia_clock_callback *cb,
+					   void *user_data,
+					   pjmedia_clock **p_clock);
+
+/**
+ * Start the clock. For clock created with asynchronous flag set to TRUE,
+ * this may start a worker thread for the clock (depending on the 
+ * backend clock implementation being used).
+ *
+ * @param clock		    The media clock.
+ *
+ * @return		    PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock);
+
+
+/**
+ * Stop the clock.
+ *
+ * @param clock		    The media clock.
+ *
+ * @return		    PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock);
+
+
+
+/**
+ * Poll the media clock, and execute the callback when the clock tick has
+ * elapsed. This operation is only valid if the clock is created with async
+ * flag set to FALSE.
+ *
+ * @param clock		    The media clock.
+ * @param wait		    If non-zero, then the function will block until
+ *			    a clock tick elapsed and callback has been called.
+ * @param ts		    Optional argument to receive the current 
+ *			    timestamp.
+ *
+ * @return		    Non-zero if clock tick has elapsed, or FALSE if
+ *			    the function returns before a clock tick has
+ *			    elapsed.
+ */
+PJ_DECL(pj_bool_t) pjmedia_clock_wait(pjmedia_clock *clock,
+				      pj_bool_t wait,
+				      pj_timestamp *ts);
+
+
+/**
+ * Destroy the clock.
+ *
+ * @param clock		    The media clock.
+ *
+ * @return		    PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock);
+
+
+
+PJ_END_DECL
+
+
+
+#endif	/* __PJMEDIA_CLOCK_H__ */
+
Index: pjproject/trunk/pjmedia/include/pjmedia/master_port.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/master_port.h	(revision 404)
+++ pjproject/trunk/pjmedia/include/pjmedia/master_port.h	(revision 404)
@@ -0,0 +1,105 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#ifndef __PJMEDIA_MASTER_PORT_H__
+#define __PJMEDIA_MASTER_PORT_H__
+
+
+/**
+ * @file master_port.h
+ * @brief Master port.
+ */
+#include <pjmedia/port.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for master port.
+ * A master port has two media ports connected to it, i.e. downstream and
+ * upstream ports. The media stream flowing to the downstream port is called
+ * encoding or send direction, and media stream flowing to the upstream port
+ * is called decoding or receive direction.
+ *
+ * A master port has a "clock" that periodically passes the media frame from 
+ * downstream to upstream ports, and vice versa. In each run, it retrieves 
+ * media frame from one side with #pjmedia_port_get_frame(), and passes the 
+ * media frame to the other side with #pjmedia_port_put_frame(). In each run,
+ * this process is done for twice, i.e. one for each direction.
+ */
+typedef struct pjmedia_master_port pjmedia_master_port;
+
+
+/**
+ * Create a master port.
+ *
+ * @param pool		Pool to allocate master port from.
+ * @param u_port	Upstream port.
+ * @param d_port	Downstream port.
+ * @param options	Options flags.
+ * @param p_m		Pointer to receive the master port instance.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_create(pj_pool_t *pool,
+						pjmedia_port *u_port,
+						pjmedia_port *d_port,
+						unsigned options,
+						pjmedia_master_port **p_m);
+
+
+
+/**
+ * Start the media flow.
+ *
+ * @param m		The master port.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m);
+
+
+
+/**
+ * Stop the media flow.
+ *
+ * @param m		The master port.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m);
+
+
+/**
+ * Destroy the master port, and optionally destroy the upstream and 
+ * downstream ports.
+ *
+ * @param m		The master port.
+ *
+ * @return		PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m);
+
+
+
+PJ_END_DECL
+
+
+#endif	/* __PJMEDIA_MASTER_PORT_H__ */
+
Index: pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c	(revision 404)
+++ pjproject/trunk/pjmedia/src/pjmedia/clock_thread.c	(revision 404)
@@ -0,0 +1,247 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia/clock.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/os.h>
+#include <pj/pool.h>
+
+
+/*
+ * Implementation of media clock with OS thread.
+ */
+
+
+struct pjmedia_clock
+{
+    pj_timestamp	     freq;
+    pj_timestamp	     interval;
+    pj_timestamp	     next_tick;
+    pj_timestamp	     timestamp;
+    unsigned		     samples_per_frame;
+    unsigned		     options;
+    pjmedia_clock_callback  *cb;
+    void		    *user_data;
+    pj_thread_t		    *thread;
+    pj_bool_t		     running;
+    pj_bool_t		     quitting;
+};
+
+
+static int clock_thread(void *arg);
+
+
+/*
+ * Create media clock.
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
+					  unsigned clock_rate,
+					  unsigned samples_per_frame,
+					  unsigned options,
+					  pjmedia_clock_callback *cb,
+					  void *user_data,
+					  pjmedia_clock **p_clock)
+{
+    pjmedia_clock *clock;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(pool && clock_rate && samples_per_frame && p_clock,
+		     PJ_EINVAL);
+
+    clock = pj_pool_alloc(pool, sizeof(pjmedia_clock));
+
+    
+    status = pj_get_timestamp_freq(&clock->freq);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    clock->interval.u64 = samples_per_frame * clock->freq.u64 / clock_rate;
+    clock->next_tick.u64 = 0;
+    clock->timestamp.u64 = 0;
+    clock->samples_per_frame = samples_per_frame;
+    clock->options = options;
+    clock->cb = cb;
+    clock->user_data = user_data;
+    clock->thread = NULL;
+    clock->running = PJ_FALSE;
+    clock->quitting = PJ_FALSE;
+    
+    status = pj_thread_create(pool, "clock", &clock_thread, clock,
+			      0, 0, &clock->thread);
+    if (status != PJ_SUCCESS)
+	return status;
+
+
+    *p_clock = clock;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Start the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock)
+{
+    pj_timestamp now;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    status = pj_get_timestamp(&now);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    clock->next_tick.u64 = now.u64 + clock->interval.u64;
+    clock->running = PJ_TRUE;
+
+    return status;
+}
+
+
+/*
+ * Stop the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)
+{
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    clock->running = PJ_FALSE;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Poll the clock. 
+ */
+PJ_DEF(pj_bool_t) pjmedia_clock_wait( pjmedia_clock *clock,
+				      pj_bool_t wait,
+				      pj_timestamp *ts)
+{
+    pj_timestamp now;
+    pj_status_t status;
+
+    PJ_ASSERT_RETURN(clock != NULL, PJ_FALSE);
+    PJ_ASSERT_RETURN((clock->options & PJMEDIA_CLOCK_NO_ASYNC) != 0,
+		     PJ_FALSE);
+    PJ_ASSERT_RETURN(clock->running, PJ_FALSE);
+
+    status = pj_get_timestamp(&now);
+    if (status != PJ_SUCCESS)
+	return PJ_FALSE;
+
+    /* Wait for the next tick to happen */
+    if (now.u64 < clock->next_tick.u64) {
+	unsigned msec;
+
+	if (!wait)
+	    return PJ_FALSE;
+
+	msec = pj_elapsed_msec(&now, &clock->next_tick);
+	pj_thread_sleep(msec);
+    }
+
+    /* Call callback, if any */
+    if (clock->cb)
+	(*clock->cb)(&clock->timestamp, clock->user_data);
+
+    /* Report timestamp to caller */
+    if (ts)
+	ts->u64 = clock->timestamp.u64;
+
+    /* Increment timestamp */
+    clock->timestamp.u64 += clock->samples_per_frame;
+
+    /* Calculate next tick */
+    clock->next_tick.u64 += clock->interval.u64;
+
+    /* Done */
+    return PJ_TRUE;
+}
+
+
+/*
+ * Clock thread
+ */
+static int clock_thread(void *arg)
+{
+    pj_timestamp now;
+    pjmedia_clock *clock = arg;
+
+    /* Get the first tick */
+    pj_get_timestamp(&clock->next_tick);
+    clock->next_tick.u64 += clock->interval.u64;
+
+
+    while (!clock->quitting) {
+
+	pj_get_timestamp(&now);
+
+	/* Wait for the next tick to happen */
+	if (now.u64 < clock->next_tick.u64) {
+	    unsigned msec;
+	    msec = pj_elapsed_msec(&now, &clock->next_tick);
+	    pj_thread_sleep(msec);
+	}
+
+	/* Skip if not running */
+	if (!clock->running)
+	    continue;
+
+	/* Call callback, if any */
+	if (clock->cb)
+	    (*clock->cb)(&clock->timestamp, clock->user_data);
+
+	/* Increment timestamp */
+	clock->timestamp.u64 += clock->samples_per_frame;
+
+	/* Calculate next tick */
+	clock->next_tick.u64 += clock->interval.u64;
+
+
+    }
+
+    return 0;
+}
+
+
+/*
+ * Destroy the clock. 
+ */
+PJ_DEF(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock)
+{
+    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
+
+    clock->running = PJ_FALSE;
+    clock->quitting = PJ_TRUE;
+
+    if (clock->thread) {
+	pj_thread_join(clock->thread);
+	pj_thread_destroy(clock->thread);
+	clock->thread = NULL;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+
+
+
Index: pjproject/trunk/pjmedia/src/pjmedia/master_port.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/master_port.c	(revision 404)
+++ pjproject/trunk/pjmedia/src/pjmedia/master_port.c	(revision 404)
@@ -0,0 +1,194 @@
+/* $Id$ */
+/* 
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+ */
+#include <pjmedia/master_port.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+
+
+struct pjmedia_master_port
+{
+    unsigned	     options;
+    pjmedia_clock   *clock;
+    pjmedia_port    *u_port;
+    pjmedia_port    *d_port;
+    unsigned	     buff_size;
+    void	    *buff;
+};
+
+
+static void clock_callback(const pj_timestamp *ts, void *user_data);
+
+
+/*
+ * Create a master port.
+ *
+ */
+PJ_DEF(pj_status_t) pjmedia_master_port_create( pj_pool_t *pool,
+						pjmedia_port *u_port,
+						pjmedia_port *d_port,
+						unsigned options,
+						pjmedia_master_port **p_m)
+{
+    pjmedia_master_port *m;
+    unsigned clock_rate;
+    unsigned samples_per_frame;
+    unsigned bytes_per_frame;
+    pj_status_t status;
+
+    /* Sanity check */
+    PJ_ASSERT_RETURN(pool && u_port && d_port && p_m, PJ_EINVAL);
+
+
+    /* Both ports MUST have the equal ptime */
+    PJ_ASSERT_RETURN(u_port->info.sample_rate/u_port->info.samples_per_frame==
+		     d_port->info.sample_rate/d_port->info.samples_per_frame,
+		     PJMEDIA_ENCSAMPLESPFRAME);
+
+
+    /* Get clock_rate and samples_per_frame from one of the port. */
+    clock_rate = u_port->info.sample_rate;
+    samples_per_frame = u_port->info.samples_per_frame;
+
+
+    /* Get the bytes_per_frame value, to determine the size of the
+     * buffer. We take the larger size of the two ports.
+     */
+    bytes_per_frame = u_port->info.bytes_per_frame;
+    if (d_port->info.bytes_per_frame > bytes_per_frame)
+	bytes_per_frame = d_port->info.bytes_per_frame;
+
+
+    /* Create the master port instance */
+    m = pj_pool_zalloc(pool, sizeof(pjmedia_master_port));
+    m->options = options;
+    m->u_port = u_port;
+    m->d_port = d_port;
+
+    
+    /* Create buffer */
+    m->buff_size = bytes_per_frame;
+    m->buff = pj_pool_alloc(pool, m->buff_size);
+    if (!m->buff)
+	return PJ_ENOMEM;
+
+
+    /* Create media clock */
+    status = pjmedia_clock_create(pool, clock_rate, samples_per_frame, 0,
+				  &clock_callback, m, &m->clock);
+    if (status != PJ_SUCCESS)
+	return status;
+
+
+    /* Done */
+    *p_m = m;
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Start the media flow.
+ */
+PJ_DEF(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m)
+{
+    PJ_ASSERT_RETURN(m && m->clock, PJ_EINVAL);
+    PJ_ASSERT_RETURN(m->u_port && m->d_port, PJ_EINVALIDOP);
+
+    return pjmedia_clock_start(m->clock);
+}
+
+
+
+/*
+ * Stop the media flow.
+ */
+PJ_DEF(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m)
+{
+    PJ_ASSERT_RETURN(m && m->clock, PJ_EINVAL);
+    
+    return pjmedia_clock_stop(m->clock);
+}
+
+
+/*
+ * Callback to be called for each clock ticks.
+ */
+static void clock_callback(const pj_timestamp *ts, void *user_data)
+{
+    pjmedia_master_port *m = user_data;
+    pjmedia_frame frame;
+    pj_status_t status;
+
+
+    /* Get frame from upstream port and pass it to downstream port */
+    pj_memset(&frame, 0, sizeof(frame));
+    frame.buf = m->buff;
+    frame.size = m->buff_size;
+    frame.timestamp.u64 = ts->u64;
+
+    status = pjmedia_port_get_frame(m->u_port, &frame);
+    if (status != PJ_SUCCESS)
+	frame.type = PJMEDIA_FRAME_TYPE_NONE;
+
+    status = pjmedia_port_put_frame(m->d_port, &frame);
+
+    /* Get frame from downstream port and pass it to upstream port */
+    pj_memset(&frame, 0, sizeof(frame));
+    frame.buf = m->buff;
+    frame.size = m->buff_size;
+    frame.timestamp.u64 = ts->u64;
+
+    status = pjmedia_port_get_frame(m->d_port, &frame);
+    if (status != PJ_SUCCESS)
+	frame.type = PJMEDIA_FRAME_TYPE_NONE;
+
+    status = pjmedia_port_put_frame(m->u_port, &frame);
+}
+
+
+/*
+ * Destroy the master port, and optionally destroy the u_port and 
+ * d_port ports.
+ */
+PJ_DEF(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m)
+{
+    PJ_ASSERT_RETURN(m, PJ_EINVAL);
+
+    if (m->clock) {
+	pjmedia_clock_destroy(m->clock);
+	m->clock = NULL;
+    }
+
+    if (m->u_port) {
+	pjmedia_port_destroy(m->u_port);
+	m->u_port = NULL;
+    }
+
+    if (m->d_port) {
+	pjmedia_port_destroy(m->d_port);
+	m->d_port = NULL;
+    }
+
+    return PJ_SUCCESS;
+}
+
+
