Index: pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4608)
@@ -26,4 +26,6 @@
 	%template(IntVector) std::vector<int>;
 	%template(AuthCredInfoVector) std::vector<AuthCredInfo>;
+	%template(SipMultipartPartVector) std::vector<SipMultipartPart>;
+	%template(SipHeaderVector) std::vector<SipHeader>;
 }
 
Index: pjproject/branches/projects/pjsua2/pjsip/build/Makefile
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/build/Makefile	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/build/Makefile	(revision 4608)
@@ -90,5 +90,5 @@
 export PJSUA2_LIB_SRCDIR = ../src/pjsua2
 export PJSUA2_LIB_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
-			   endpoint.o types.o
+			   account.o endpoint.o types.o
 export PJSUA2_LIB_CFLAGS += $(_CFLAGS) $(PJ_VIDEO_CFLAGS)
 export PJSUA2_LIB_CXXFLAGS = $(PJSUA2_LIB_CFLAGS) 
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/account.hpp	(revision 4608)
@@ -25,4 +25,5 @@
  */
 #include <pjsua-lib/pjsua.h>
+#include <pjsua2/types.hpp>
 
 /**
@@ -37,4 +38,10 @@
  */
 
+/** PJSUA2 API is inside pj namespace */
+namespace pj
+{
+using std::string;
+using std::vector;
+
 /**
  * Account registration config. This will be specified in AccountConfig.
@@ -49,5 +56,5 @@
      * value is empty, no account registration will be performed.
      */
-    String		registrarUri;
+    string		registrarUri;
 
     /**
@@ -64,5 +71,5 @@
      * request.
      */
-    StringVector	headers;
+    SipHeaderVector	headers;
 
     /**
@@ -102,5 +109,5 @@
      * Default: PJSIP_REGISTER_CLIENT_DELAY_BEFORE_REFRESH, 5 seconds
      */
-    unsigned		delayBeforeRefresh;
+    unsigned		delayBeforeRefreshSec;
 
     /**
@@ -122,9 +129,12 @@
 
     /**
-     * Specify whether REGISTER requests will use the proxy settings
-     * of this account. If zero, the REGISTER request will not have any
-     * Route headers.
-     *
-     * Default: 1 (use account proxy)
+     * Specify how the registration uses the outbound and account proxy
+     * settings. This controls if and what Route headers will appear in
+     * the REGISTER request of this account. The value is bitmask combination
+     * of PJSUA_REG_USE_OUTBOUND_PROXY and PJSUA_REG_USE_ACC_PROXY bits.
+     * If the value is set to 0, the REGISTER request will not use any proxy
+     * (i.e. it will not have any Route headers).
+     *
+     * Default: 3 (PJSUA_REG_USE_OUTBOUND_PROXY | PJSUA_REG_USE_ACC_PROXY)
      */
     unsigned		proxyUse;
@@ -241,4 +251,17 @@
      */
     pjsua_sip_timer_use	timerUse;
+
+    /**
+     * Specify minimum Session Timer expiration period, in seconds.
+     * Must not be lower than 90. Default is 90.
+     */
+    unsigned		timerMinSESec;
+
+    /**
+     * Specify Session Timer expiration period, in seconds.
+     * Must not be lower than timerMinSE. Default is 1800.
+     */
+    unsigned		timerSessExpiresSec;
+
 };
 
@@ -252,5 +275,5 @@
      * subscription request.
      */
-    StringVector	subHeaders;
+    SipHeaderVector	headers;
 
     /**
@@ -390,4 +413,14 @@
      */
     bool		iceNoRtcp;
+
+    /**
+     * Always send re-INVITE/UPDATE after ICE negotiation regardless of whether
+     * the default ICE transport address is changed or not. When this is set
+     * to False, re-INVITE/UPDATE will be sent only when the default ICE
+     * transport address is changed.
+     *
+     * Default: yes
+     */
+    bool		iceAlwaysUpdate;
 
     /**
@@ -440,22 +473,15 @@
      * Default: TRUE
      */
-    bool		contactRewriteEnabled;
+    int			contactRewriteUse;
 
     /**
      * Specify how Contact update will be done with the registration, if
-     * contactRewriteEnabled is enabled.
-     *
-     * If set to 1, the Contact update will be done by sending unregistration
-     * to the currently registered Contact, while simultaneously sending new
-     * registration (with different Call-ID) for the updated Contact.
-     *
-     * If set to 2, the Contact update will be done in a single, current
-     * registration session, by removing the current binding (by setting its
-     * Contact's expires parameter to zero) and adding a new Contact binding,
-     * all done in a single request.
-     *
-     * Value 1 is the legacy behavior.
-     *
-     * Default value: PJSUA_CONTACT_REWRITE_METHOD (2)
+     * \a contactRewriteEnabled is enabled. The value is bitmask combination of
+     * \a pjsua_contact_rewrite_method. See also pjsua_contact_rewrite_method.
+     *
+     * Value PJSUA_CONTACT_REWRITE_UNREGISTER(1) is the legacy behavior.
+     *
+     * Default value: PJSUA_CONTACT_REWRITE_METHOD
+     *   (PJSUA_CONTACT_REWRITE_NO_UNREG | PJSUA_CONTACT_REWRITE_ALWAYS_UPDATE)
      */
     int			contactRewriteMethod;
@@ -469,5 +495,17 @@
      * Default: TRUE
      */
-    bool		viaRewriteEnabled;
+    int			viaRewriteUse;
+
+    /**
+     * This option controls whether the IP address in SDP should be replaced
+     * with the IP address found in Via header of the REGISTER response, ONLY
+     * when STUN and ICE are not used. If the value is FALSE (the original
+     * behavior), then the local IP address will be used. If TRUE, and when
+     * STUN and ICE are disabled, then the IP address found in registration
+     * response will be used.
+     *
+     * Default: PJ_FALSE (no)
+     */
+    int			sdpNatRewriteUse;
 
     /**
@@ -484,5 +522,5 @@
      * Default: TRUE
      */
-    bool		sipOutboundEnabled;
+    int			sipOutboundUse;
 
     /**
@@ -531,5 +569,5 @@
 {
     /**
-     * Media transport configuration.
+     * Media transport (RTP) configuration.
      */
     TransportConfig	transportConfig;
@@ -574,35 +612,9 @@
      */
     int			srtpSecureSignaling;
-};
-
-/**
- * Video stream rate control config. This will be specified in
- * AccountVideoConfig.
- */
-struct VidRateControlConfig
-{
-    /**
-     * Rate control method.
-     *
-     * Default: PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING.
-     */
-    pjmedia_vid_stream_rc_method    method;
-
-    /**
-     * Upstream/outgoing bandwidth. If this is set to zero, the video stream
-     * will use codec maximum bitrate setting.
-     *
-     * Default: 0 (follow codec maximum bitrate).
-     */
-    unsigned			    bandwidth;
-
-    /** Default constructor */
-    VidRateControlConfig();
-
-    /** Convert to pj */
-    pjmedia_vid_stream_rc_config toPj() const;
-
-    /** Convert from pj */
-    void fromPj(const pjmedia_vid_stream_rc_config &prm);
+
+    /**
+     * Specify whether IPv6 should be used on media. Default is not used.
+     */
+    pjsua_ipv6_use	ipv6Use;
 };
 
@@ -626,5 +638,5 @@
      * Default: False
      */
-    bool		autoShowIncoming;
+    bool			autoShowIncoming;
 
     /**
@@ -641,5 +653,5 @@
      * Default: False
      */
-    bool		autoTransmitOutgoing;
+    bool			autoTransmitOutgoing;
 
     /**
@@ -649,5 +661,5 @@
      * Default: 0
      */
-    unsigned		windowFlags;
+    unsigned			windowFlags;
 
     /**
@@ -658,5 +670,5 @@
      * Default: PJMEDIA_VID_DEFAULT_CAPTURE_DEV
      */
-    pjmedia_vid_dev_index defaultCaptureDevice;
+    pjmedia_vid_dev_index 	defaultCaptureDevice;
 
     /**
@@ -665,10 +677,20 @@
      * Default: PJMEDIA_VID_DEFAULT_RENDER_DEV
      */
-    pjmedia_vid_dev_index defaultRenderDevice;
-
-    /**
-     * Specify the send rate control for video stream.
-     */
-    VidRateControlConfig  rateControlConfig;
+    pjmedia_vid_dev_index 	defaultRenderDevice;
+
+    /**
+     * Rate control method.
+     *
+     * Default: PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING.
+     */
+    pjmedia_vid_stream_rc_method rateControlMethod;
+
+    /**
+     * Upstream/outgoing bandwidth. If this is set to zero, the video stream
+     * will use codec maximum bitrate setting.
+     *
+     * Default: 0 (follow codec maximum bitrate).
+     */
+    unsigned			rateControlBandwidth;
 };
 
@@ -692,5 +714,5 @@
      * This field is mandatory.
      */
-    String		uri;
+    string		idUri;
 
     /**
@@ -734,4 +756,5 @@
     AccountVideoConfig	videoConfig;
 
+public:
     /**
      * Default constructor will initialize with default values.
@@ -740,5 +763,9 @@
 
     /**
-     * Convert to pjsip.
+     * This will return a temporary pjsua_acc_config instance, which contents
+     * are only valid as long as this AccountConfig structure remains valid
+     * AND no modifications are done to it AND no further toPj() function call
+     * is made. Any call to toPj() function will invalidate the content of
+     * temporary pjsua_acc_config that was returned by the previous call.
      */
     pjsua_acc_config toPj() const;
@@ -747,5 +774,27 @@
      * Initialize from pjsip.
      */
-    void fromPj(const pjsua_acc_config &prm);
+    void fromPj(const pjsua_acc_config &prm, const pjsua_media_config *mcfg);
+
+};
+
+/**
+ * This describes account presence status.
+ */
+struct AccountPresenceStatus
+{
+    /** Basic status. */
+    bool		isOnline;
+
+    /** Activity type. */
+    pjrpid_activity	activity;
+
+    /** Optional text describing the person/element. */
+    string		note;
+
+    /** Optional RPID ID string. */
+    string		rpidId;
+
+public:
+    AccountPresenceStatus();
 };
 
@@ -821,17 +870,59 @@
 
 /**
- * This structure contains parameters for onIncomingCall() callback.
- */
-struct IncomingCallParam
-{
-    // rdata
-};
-
-/**
- * This structure contains parameters for onRegState() callback.
- */
-struct RegStateParam
-{
-    // reginfo
+ * This structure contains parameters for onIncomingCall() account callback.
+ */
+struct OnIncomingCallParam
+{
+    /**
+     * The library call index allocated for the new call.
+     */
+    int			callIndex;
+
+    /**
+     * The incoming INVITE request.
+     */
+    SipRxData		rdata;
+};
+
+/**
+ * This structure contains parameters for onRegStarted() account callback.
+ */
+struct OnRegStartedParam
+{
+    /**
+     * True for registration and False for unregistration.
+     */
+    bool renew;
+};
+
+/**
+ * This structure contains parameters for onRegState() account callback.
+ */
+struct OnRegStateParam
+{
+    /**
+     * Registration operation status.
+     */
+    pj_status_t		status;
+
+    /**
+     * SIP status code received.
+     */
+    int			code;
+
+    /**
+     * SIP reason phrase received.
+     */
+    pj_str_t		reason;
+
+    /**
+     * The incoming message.
+     */
+    SipRxData		rdata;
+
+    /**
+     * Next expiration interval.
+     */
+    int			expiration;
 };
 
@@ -839,32 +930,15 @@
  * This structure contains parameters for onIncomingSubscribe() callback.
  */
-struct IncomingSubscribeParam
-{
-    /*
-    * @param srv_pres	    Server presence subscription instance. If
-    *			    application delays the acceptance of the request,
-    *			    it will need to specify this object when calling
-    *			    #pjsua_pres_notify().
-    * @param acc_id	    Account ID most appropriate for this request.
-    * @param buddy_id	    ID of the buddy matching the sender of the
-    *			    request, if any, or PJSUA_INVALID_ID if no
-    *			    matching buddy is found.
-    * @param from	    The From URI of the request.
-    * @param rdata	    The incoming request.
-    * @param code	    The status code to respond to the request. The
-    *			    default value is 200. Application may set this
-    *			    to other final status code to accept or reject
-    *			    the request.
-    * @param reason	    The reason phrase to respond to the request.
-    * @param msg_data	    If the application wants to send additional
-    *			    headers in the response, it can put it in this
-    *			    parameter.
-    */
-
-    //pjsua_srv_pres *srv_pres,
-    // pjsua_buddy_id buddy_id,
-    // const pj_str_t *from,
-    // pjsip_rx_data *rdata,
-    // pjsua_msg_data *msg_data
+struct OnIncomingSubscribeParam
+{
+    /**
+     *  Sender URI.
+     */
+    string		fromUri;
+
+    /**
+     * The incoming message.
+     */
+    SipRxData		rdata;
 
     /**
@@ -873,10 +947,137 @@
      * reject the request.
      */
-    pjsip_status_code code;
+    pjsip_status_code	code;
 
     /**
      * The reason phrase to respond to the request.
      */
-    string reason;
+    string		reason;
+
+    /**
+     * Additional data to be sent with the response, if any.
+     */
+    SipTxOption		txOption;
+};
+
+/**
+ * Parameters for onInstantMessage() account callback.
+ */
+struct OnInstantMessageParam
+{
+    /**
+     * Sender From URI.
+     */
+    string		fromUri;
+
+    /**
+     * To URI of the request.
+     */
+    string		toUri;
+
+    /**
+     * Contact URI of the sender.
+     */
+    string		contactUri;
+
+    /**
+     * MIME type of the message body.
+     */
+    string		contentType;
+
+    /**
+     * The message body.
+     */
+    string		msgBody;
+
+    /**
+     * The whole message.
+     */
+    SipRxData		rdata;
+};
+
+/**
+ * Parameters for onInstantMessageStatus() account callback.
+ */
+struct OnInstantMessageStatusParam
+{
+    /**
+     * Token or a user data that was associated with the pager
+     * transmission.
+     */
+    Token		userData;
+
+    /**
+     * Destination URI.
+     */
+    string		toUri;
+
+    /**
+     * The message body.
+     */
+    string		msgBody;
+
+    /**
+     * The SIP status code of the transaction.
+     */
+    pjsip_status_code	status;
+
+    /**
+     * The reason phrase of the transaction.
+     */
+    string		reason;
+
+    /**
+     * The incoming response that causes this callback to be called.
+     * If the transaction fails because of time out or transport error,
+     * the content will be empty.
+     */
+    SipRxData		rdata;
+};
+
+/**
+ * Parameters for onTypingIndication() account callback.
+ */
+struct OnTypingIndicationParam
+{
+    /**
+     * Sender/From URI.
+     */
+    string		fromUri;
+
+    /**
+     * To URI.
+     */
+    string		toUri;
+
+    /**
+     * The Contact URI.
+     */
+    string		contactUri;
+
+    /**
+     * Boolean to indicate if sender is typing.
+     */
+    bool		isTyping;
+
+    /**
+     * The whole message buffer.
+     */
+    SipRxData		rdata;
+};
+
+/**
+ * Parameters for onMwiInfo() account callback.
+ */
+struct OnMwiInfoParam
+{
+    /**
+     * MWI subscription state.
+     */
+    pjsip_evsub_state	state;
+
+    /**
+     * The whole message buffer.
+     */
+    SipRxData		rdata;
 };
 
@@ -895,5 +1096,16 @@
      * @param prm	Callback parameter.
      */
-    virtual void onIncomingCall(IncomingCallParam &prm)
+    virtual void onIncomingCall(OnIncomingCallParam &prm)
+    {}
+
+    /**
+     * Notify application when registration or unregistration has been
+     * initiated. Note that this only notifies the initial registration
+     * and unregistration. Once registration session is active, subsequent
+     * refresh will not cause this callback to be called.
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onRegStarted(OnRegStartedParam &prm)
     {}
 
@@ -903,7 +1115,7 @@
      * registration details.
      *
-     * @param acc_id	    The account ID.
-     */
-    virtual void onRegState(RegStateParam &prm)
+     * @param prm	    Callback parameter.
+     */
+    virtual void onRegState(OnRegStateParam &prm)
     {}
 
@@ -937,8 +1149,46 @@
      * Application MUST return from this callback immediately (e.g. it must
      * not block in this callback while waiting for user confirmation).
-     */
-    virtual void onIncomingSubscribe(IncomingSubscribeParam &prm)
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onIncomingSubscribe(OnIncomingSubscribeParam &prm)
     {}
 
+    /**
+     * Notify application on incoming instant message or pager (i.e. MESSAGE
+     * request) that was received outside call context.
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onInstantMessage(OnInstantMessageParam &prm)
+    {}
+
+    /**
+     * Notify application about the delivery status of outgoing pager/instant
+     * message (i.e. MESSAGE) request.
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onInstantMessageStatus(OnInstantMessageStatusParam &prm)
+    {}
+
+    /**
+     * Notify application about typing indication.
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onTypingIndication(OnTypingIndicationParam &prm)
+    {}
+
+    /**
+     * Notification about MWI (Message Waiting Indication) status change.
+     * This callback can be called upon the status change of the
+     * SUBSCRIBE request (for example, 202/Accepted to SUBSCRIBE is received)
+     * or when a NOTIFY reqeust is received.
+     *
+     * @param prm	    Callback parameter.
+     */
+    virtual void onMwiInfo(OnMwiInfoParam &prm)
+    {}
 };
 
@@ -960,5 +1210,101 @@
 {
 public:
-    void setTransport();
+    /**
+     * Check if this account is still valid.
+     *
+     * @return			True if it is.
+     */
+    bool isValid() const;
+
+    /**
+     * Set this as default account to be used when incoming and outgoing
+     * requests don't match any accounts.
+     *
+     * @return			PJ_SUCCESS on success.
+     */
+    void setDefault() throw(Error);
+
+    /**
+     * Check if this account is the default account. Default account will be
+     * used for incoming and outgoing requests that don't match any other
+     * accounts.
+     *
+     * @return			True if this is the default account.
+     */
+    bool isDefault() const;
+
+    /**
+     * Get PJSUA-LIB account ID or index associated with this account.
+     *
+     * @return			Integer greater than or equal to zero.
+     */
+    int getIndex() const;
+
+    /**
+     * Set arbitrary data to be associated with the account.
+     *
+     * @param user_data		User/application data.
+     */
+    void setUserData(Token user_data);
+
+    /**
+     * Get the user data that was associated with the account.
+     *
+     * @return			The user data.
+     */
+    Token getUserData() const;
+
+    /**
+     * Get account info.
+     *
+     * @return			Account info.
+     */
+    AccountInfo getInfo() const;
+
+    /**
+     * Modify the account to use the specified account configuration.
+     * Depending on the changes, this may cause unregistration or
+     * reregistration on the account.
+     *
+     * @param cfg 		New account config to be applied to the account.
+     */
+    void modify(const AccountConfig &acc) throw(Error);
+
+    /**
+     * Update registration or perform unregistration. Application normally
+     * only needs to call this function if it wants to manually update the
+     * registration or to unregister from the server.
+     *
+     * @param renew		If False, this will start unregistration
+     * 				process.
+     */
+    void setRegistration(bool renew) throw(Error);
+
+    /**
+     * Set or modify account's presence online status to be advertised to
+     * remote/presence subscribers. This would trigger the sending of
+     * outgoing NOTIFY request if there are server side presence subscription
+     * for this account, and/or outgoing PUBLISH if presence publication is
+     * enabled for this account.
+     *
+     * @param pres_st		Presence online status.
+     */
+    void setOnlineStatus(const AccountPresenceStatus &pres_st) throw(Error);
+
+    /**
+     * Lock/bind this account to a specific transport/listener. Normally
+     * application shouldn't need to do this, as transports will be selected
+     * automatically by the library according to the destination.
+     *
+     * When account is locked/bound to a specific transport, all outgoing
+     * requests from this account will use the specified transport (this
+     * includes SIP registration, dialog (call and event subscription), and
+     * out-of-dialog requests such as MESSAGE).
+     *
+     * Note that transport id may be specified in AccountConfig too.
+     *
+     * @param tp_id		The transport ID.
+     */
+    void setTransport(TransportId tp_id) throw(Error);
 
 protected:
@@ -968,4 +1314,6 @@
 };
 
+} // namespace pj
+
 /**
  * @}  // PJSUA2_ACC
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4608)
@@ -40,4 +40,126 @@
 
 
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Argument to EpCallback::onNatDetectionComplete() callback.
+ */
+struct OnNatDetectionCompleteParam
+{
+    /**
+     * Status of the detection process. If this value is not PJ_SUCCESS,
+     * the detection has failed and \a nat_type field will contain
+     * PJ_STUN_NAT_TYPE_UNKNOWN.
+     */
+    pj_status_t		status;
+
+    /**
+     * The text describing the status, if the status is not PJ_SUCCESS.
+     */
+    string		reason;
+
+    /**
+     * This contains the NAT type as detected by the detection procedure.
+     * This value is only valid when the \a status is PJ_SUCCESS.
+     */
+    pj_stun_nat_type	natType;
+
+    /**
+     * Text describing that NAT type.
+     */
+    string		natTypeName;
+
+};
+
+/**
+ * Argument to EpCallback::onNatCheckStunServersComplete() callback.
+ */
+struct OnNatCheckStunServersCompleteParam
+{
+    /**
+     * Arbitrary user data that was passed to Endpoint::natCheckStunServers()
+     * function.
+     */
+    Token		userData;
+
+    /**
+     * This will contain PJ_SUCCESS if at least one usable STUN server
+     * is found, otherwise it will contain the last error code during
+     * the operation.
+     */
+    pj_status_t		status;
+
+    /**
+     * The server name that yields successful result. This will only
+     * contain value if status is successful.
+     */
+    string		name;
+
+    /**
+     * The server IP address and port in "IP:port" format. This will only
+     * contain value if status is successful.
+     */
+    SocketAddress	addr;
+};
+
+/**
+ * Parameter of EpCallback::OnTimer() callback.
+ */
+struct OnTimerParam
+{
+    /**
+     * Arbitrary user data that was passed to Endpoint::utilTimerSchedule()
+     * function.
+     */
+    Token		userData;
+
+    /**
+     * The interval of this timer, in miliseconds.
+     */
+    unsigned		msecDelay;
+};
+
+/**
+ * Parameter of EpCallback::onTransportState() callback.
+ */
+struct OnTransportStateParam
+{
+    /**
+     * The transport handle.
+     */
+    TransportHandle	hnd;
+
+    /**
+     * Transport current state.
+     */
+    pjsip_transport_state state;
+
+    /**
+     * The last error code related to the transport state.
+     */
+    pj_status_t		lastError;
+};
+
+/**
+ * Parameter of EpCallback::onSelectAccount() callback.
+ */
+struct OnSelectAccountParam
+{
+    /**
+     * The incoming request.
+     */
+    SipRxData		rdata;
+
+    /**
+     * The account index to be used to handle the request.
+     * Upon entry, this will be filled by the account index
+     * chosen by the library. Application may change it to
+     * another value to use another account.
+     */
+    int			accountIndex;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
 /**
  * Interface for receiving callbacks from the library. Application inherits
@@ -58,5 +180,5 @@
      */
     virtual void onNatDetectionComplete(
-			const NatDetectionCompleteParam &prm)
+			const OnNatDetectionCompleteParam &prm)
     {}
 
@@ -68,5 +190,5 @@
      */
     virtual void onNatCheckStunServersComplete(
-			const NatCheckStunServersCompleteParam &prm)
+			const OnNatCheckStunServersCompleteParam &prm)
     {}
 
@@ -76,6 +198,6 @@
      * @param prm	Callback parameters.
      */
-    virtual void onTransportStateChanged(
-			const TransportStateChangedParam &prm)
+    virtual void onTransportState(
+			const OnTransportStateParam &prm)
     {}
 
@@ -86,7 +208,441 @@
      * @param prm	Callback parameters.
      */
-    virtual void OnTimerComplete(const TimerCompleteParam &prm)
+    virtual void onTimer(const OnTimerParam &prm)
     {}
-};
+
+    /**
+     * This callback can be used by application to override the account
+     * to be used to handle an incoming message. Initially, the account to
+     * be used will be calculated automatically by the library. This initial
+     * account will be used if application does not implement this callback,
+     * or application sets an invalid account upon returning from this
+     * callback.
+     *
+     * Note that currently the incoming messages requiring account assignment
+     * are INVITE, MESSAGE, SUBSCRIBE, and unsolicited NOTIFY. This callback
+     * may be called before the callback of the SIP event itself, i.e:
+     * incoming call, pager, subscription, or unsolicited-event.
+     *
+     * @param prm	Callback parameters.
+     */
+    virtual void onSelectAccount(OnSelectAccountParam &prm)
+    {}
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+struct UaConfig
+{
+    /**
+     * Maximum calls to support (default: 4). The value specified here
+     * must be smaller than the compile time maximum settings
+     * PJSUA_MAX_CALLS, which by default is 32. To increase this
+     * limit, the library must be recompiled with new PJSUA_MAX_CALLS
+     * value.
+     */
+    unsigned		maxCalls;
+
+    /**
+     * Number of worker threads. Normally application will want to have at
+     * least one worker thread, unless when it wants to poll the library
+     * periodically, which in this case the worker thread can be set to
+     * zero.
+     */
+    unsigned		threadCnt;
+
+    /**
+     * Array of nameservers to be used by the SIP resolver subsystem.
+     * The order of the name server specifies the priority (first name
+     * server will be used first, unless it is not reachable).
+     */
+    StringVector	nameserver;
+
+    /**
+     * Optional user agent string (default empty). If it's empty, no
+     * User-Agent header will be sent with outgoing requests.
+     */
+    string		userAgent;
+
+    /**
+     * Array of STUN servers to try. The library will try to resolve and
+     * contact each of the STUN server entry until it finds one that is
+     * usable. Each entry may be a domain name, host name, IP address, and
+     * it may contain an optional port number. For example:
+     *	- "pjsip.org" (domain name)
+     *	- "sip.pjsip.org" (host name)
+     *	- "pjsip.org:33478" (domain name and a non-standard port number)
+     *	- "10.0.0.1:3478" (IP address and port number)
+     *
+     * When nameserver is configured in the \a pjsua_config.nameserver field,
+     * if entry is not an IP address, it will be resolved with DNS SRV
+     * resolution first, and it will fallback to use DNS A resolution if this
+     * fails. Port number may be specified even if the entry is a domain name,
+     * in case the DNS SRV resolution should fallback to a non-standard port.
+     *
+     * When nameserver is not configured, entries will be resolved with
+     * #pj_gethostbyname() if it's not an IP address. Port number may be
+     * specified if the server is not listening in standard STUN port.
+     */
+    StringVector	stunServer;
+
+    /**
+     * This specifies if the library startup should ignore failure with the
+     * STUN servers. If this is set to PJ_FALSE, the library will refuse to
+     * start if it fails to resolve or contact any of the STUN servers.
+     *
+     * Default: TRUE
+     */
+    bool		stunIgnoreFailure;
+
+    /**
+     * Support for adding and parsing NAT type in the SDP to assist
+     * troubleshooting. The valid values are:
+     *	- 0: no information will be added in SDP, and parsing is disabled.
+     *	- 1: only the NAT type number is added.
+     *	- 2: add both NAT type number and name.
+     *
+     * Default: 1
+     */
+    int			natTypeInSdp;
+
+    /**
+     * Handle unsolicited NOTIFY requests containing message waiting
+     * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests
+     * which are not requested by client with SUBSCRIBE request.
+     *
+     * If this is enabled, the library will respond 200/OK to the NOTIFY
+     * request and forward the request to EpCallback.onMwiInfo() callback.
+     *
+     * See also AccountMwiConfig.enabled.
+     *
+     * Default: PJ_TRUE
+     */
+    bool	    	mwiUnsolicitedEnabled;
+
+public:
+    /**
+     * Default constructor to initialize with default values.
+     */
+    UaConfig();
+
+    /**
+     * Construct from pjsua_config.
+     */
+    void fromPj(const pjsua_config &ua_cfg);
+
+    /**
+     * Export to pjsua_config
+     */
+    pjsua_config toPj() const;
+};
+
+
+/**
+ * Data containing log entry to be written by the LogWriter.
+ */
+struct LogEntry
+{
+    /** Log verbosity level of this message */
+    int		level;
+
+    /** The log message */
+    string	msg;
+
+    /** ID of current thread */
+    long	threadId;
+
+    /** The name of the thread that writes this log */
+    string	threadName;
+};
+
+
+/**
+ * Interface for writing log messages. Applications can inherit this class
+ * and supply it in the LogConfig structure to implement custom log
+ * writing facility.
+ */
+class LogWriter
+{
+public:
+    /** Destructor */
+    virtual ~LogWriter() {}
+
+    /** Write a log entry. */
+    virtual void write(const LogEntry &entry) = 0;
+};
+
+
+/**
+ * Logging configuration, which can be (optionally) specified when calling
+ * Lib::init().
+ */
+struct LogConfig
+{
+    /** Log incoming and outgoing SIP message? Yes!  */
+    unsigned		msgLogging;
+
+    /** Input verbosity level. Value 5 is reasonable. */
+    unsigned		level;
+
+    /** Verbosity level for console. Value 4 is reasonable. */
+    unsigned		consoleLevel;
+
+    /** Log decoration. */
+    unsigned		decor;
+
+    /** Optional log filename if app wishes the library to write to log file.
+     */
+    string		filename;
+
+    /**
+     * Additional flags to be given to #pj_file_open() when opening
+     * the log file. By default, the flag is PJ_O_WRONLY. Application
+     * may set PJ_O_APPEND here so that logs are appended to existing
+     * file instead of overwriting it.
+     *
+     * Default is 0.
+     */
+    unsigned		fileFlags;
+
+    /**
+     * Custom log writer, if required. If specified, the instance of LogWriter
+     * must be kept alive througout the duration of the application.
+     */
+    LogWriter		*writer;
+
+public:
+    /** Default constructor initialises with default values */
+    LogConfig();
+
+    /** Construct from pjsua_logging_config */
+    void fromPj(const pjsua_logging_config &lc);
+
+    /** Generate pjsua_logging_config. */
+    pjsua_logging_config toPj() const;
+};
+
+
+/**
+ * This structure describes media configuration, which will be specified
+ * when calling Lib::init().
+ */
+struct MediaConfig
+{
+public:
+    /**
+     * Clock rate to be applied to the conference bridge.
+     * If value is zero, default clock rate will be used
+     * (PJSUA_DEFAULT_CLOCK_RATE, which by default is 16KHz).
+     */
+    unsigned		clockRate;
+
+    /**
+     * Clock rate to be applied when opening the sound device.
+     * If value is zero, conference bridge clock rate will be used.
+     */
+    unsigned		sndClockRate;
+
+    /**
+     * Channel count be applied when opening the sound device and
+     * conference bridge.
+     */
+    unsigned		channelCount;
+
+    /**
+     * Specify audio frame ptime. The value here will affect the
+     * samples per frame of both the sound device and the conference
+     * bridge. Specifying lower ptime will normally reduce the
+     * latency.
+     *
+     * Default value: PJSUA_DEFAULT_AUDIO_FRAME_PTIME
+     */
+    unsigned		audioFramePtime;
+
+    /**
+     * Specify maximum number of media ports to be created in the
+     * conference bridge. Since all media terminate in the bridge
+     * (calls, file player, file recorder, etc), the value must be
+     * large enough to support all of them. However, the larger
+     * the value, the more computations are performed.
+     *
+     * Default value: PJSUA_MAX_CONF_PORTS
+     */
+    unsigned		maxMediaPorts;
+
+    /**
+     * Specify whether the media manager should manage its own
+     * ioqueue for the RTP/RTCP sockets. If yes, ioqueue will be created
+     * and at least one worker thread will be created too. If no,
+     * the RTP/RTCP sockets will share the same ioqueue as SIP sockets,
+     * and no worker thread is needed.
+     *
+     * Normally application would say yes here, unless it wants to
+     * run everything from a single thread.
+     */
+    bool		hasIoqueue;
+
+    /**
+     * Specify the number of worker threads to handle incoming RTP
+     * packets. A value of one is recommended for most applications.
+     */
+    unsigned		threadCnt;
+
+    /**
+     * Media quality, 0-10, according to this table:
+     *   5-10: resampling use large filter,
+     *   3-4:  resampling use small filter,
+     *   1-2:  resampling use linear.
+     * The media quality also sets speex codec quality/complexity to the
+     * number.
+     *
+     * Default: 5 (PJSUA_DEFAULT_CODEC_QUALITY).
+     */
+    unsigned		quality;
+
+    /**
+     * Specify default codec ptime.
+     *
+     * Default: 0 (codec specific)
+     */
+    unsigned		ptime;
+
+    /**
+     * Disable VAD?
+     *
+     * Default: 0 (no (meaning VAD is enabled))
+     */
+    bool		noVad;
+
+    /**
+     * iLBC mode (20 or 30).
+     *
+     * Default: 30 (PJSUA_DEFAULT_ILBC_MODE)
+     */
+    unsigned		ilbcMode;
+
+    /**
+     * Percentage of RTP packet to drop in TX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		txDropPct;
+
+    /**
+     * Percentage of RTP packet to drop in RX direction
+     * (to simulate packet lost).
+     *
+     * Default: 0
+     */
+    unsigned		rxDropPct;
+
+    /**
+     * Echo canceller options (see #pjmedia_echo_create())
+     *
+     * Default: 0.
+     */
+    unsigned		ecOptions;
+
+    /**
+     * Echo canceller tail length, in miliseconds. Setting this to zero
+     * will disable echo cancellation.
+     *
+     * Default: PJSUA_DEFAULT_EC_TAIL_LEN
+     */
+    unsigned		ecTailLen;
+
+    /**
+     * Audio capture buffer length, in milliseconds.
+     *
+     * Default: PJMEDIA_SND_DEFAULT_REC_LATENCY
+     */
+    unsigned		sndRecLatency;
+
+    /**
+     * Audio playback buffer length, in milliseconds.
+     *
+     * Default: PJMEDIA_SND_DEFAULT_PLAY_LATENCY
+     */
+    unsigned		sndPlayLatency;
+
+    /**
+     * Jitter buffer initial prefetch delay in msec. The value must be
+     * between jb_min_pre and jb_max_pre below.
+     *
+     * Default: -1 (to use default stream settings, currently 150 msec)
+     */
+    int			jbInit;
+
+    /**
+     * Jitter buffer minimum prefetch delay in msec.
+     *
+     * Default: -1 (to use default stream settings, currently 60 msec)
+     */
+    int			jbMinPre;
+
+    /**
+     * Jitter buffer maximum prefetch delay in msec.
+     *
+     * Default: -1 (to use default stream settings, currently 240 msec)
+     */
+    int			jbMaxPre;
+
+    /**
+     * Set maximum delay that can be accomodated by the jitter buffer msec.
+     *
+     * Default: -1 (to use default stream settings, currently 360 msec)
+     */
+    int			jbMax;
+
+    /**
+     * Specify idle time of sound device before it is automatically closed,
+     * in seconds. Use value -1 to disable the auto-close feature of sound
+     * device
+     *
+     * Default : 1
+     */
+    int			sndAutoCloseTime;
+
+    /**
+     * Specify whether built-in/native preview should be used if available.
+     * In some systems, video input devices have built-in capability to show
+     * preview window of the device. Using this built-in preview is preferable
+     * as it consumes less CPU power. If built-in preview is not available,
+     * the library will perform software rendering of the input. If this
+     * field is set to PJ_FALSE, software preview will always be used.
+     *
+     * Default: PJ_TRUE
+     */
+    bool		vidPreviewEnableNative;
+
+public:
+    /** Default constructor initialises with default values */
+    MediaConfig();
+
+    /** Construct from pjsua_media_config. */
+    void fromPj(const pjsua_media_config &mc);
+
+    /** Export */
+    pjsua_media_config toPj() const;
+};
+
+
+/**
+ * Endpoint configuration
+ */
+struct EpConfig
+{
+    /** UA config */
+    UaConfig		uaConfig;
+
+    /** Logging config */
+    LogConfig		logConfig;
+
+    /** Media config */
+    MediaConfig		medConfig;
+};
+
+//////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -214,5 +770,5 @@
     /**
      * Schedule a timer with the specified interval and user data. When the
-     * interval elapsed, EpCallback::OnTimerComplete() callback will be
+     * interval elapsed, EpCallback::OnTimer() callback will be
      * called. Note that the callback may be executed by different thread,
      * depending on whether worker thread is enabled or not.
Index: pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/types.hpp	(revision 4608)
@@ -94,9 +94,9 @@
     pj_status_t	status;
 
+    /** The PJSUA API operation that throws the error. */
+    string	title;
+
     /** The error message */
     string	reason;
-
-    /** The PJSUA API operation that throws the error. */
-    string	title;
 
     /** The PJSUA source file that throws the error */
@@ -115,27 +115,45 @@
      */
     Error(pj_status_t prm_status,
+          const string &prm_title,
           const string &prm_reason,
-          const string &prm_title,
           const string &prm_src_file,
           int prm_src_line);
 };
 
-/**
- * This is a utility macro to check the status code and raise an Error
- * exception on error.
+
+/*
+ * Error utilities.
  */
 #if PJSUA2_ERROR_HAS_EXTRA_INFO
-#   define PJSUA2_CHECK_RAISE_ERROR(op, status)	\
-	    do { \
-		if (status != PJ_SUCCESS) \
-		    throw Error(status, string(), op, __FILE__, __LINE__); \
-	    } while (0)
+#   define PJSUA2_RAISE_ERROR(status)		\
+	PJSUA2_RAISE_ERROR2(status, __FUNCTION__)
+
+#   define PJSUA2_RAISE_ERROR2(status,op)	\
+	PJSUA2_RAISE_ERROR3(status, op, string())
+
+#   define PJSUA2_RAISE_ERROR3(status,op,txt)	\
+	throw Error(status, op, txt, __FILE__, __LINE__)
+
 #else
-#   define PJSUA2_CHECK_RAISE_ERROR(op, status)	\
-	    do { \
-		if (status != PJ_SUCCESS) \
-		    throw Error(status, string(), string(), string(), 0); \
-	    } while (0)
+#   define PJSUA2_RAISE_ERROR(status)		\
+	PJSUA2_RAISE_ERROR2(status, string())
+
+#   define PJSUA2_RAISE_ERROR2(status,op)	\
+	PJSUA2_RAISE_ERROR3(status, op, string())
+
+#   define PJSUA2_RAISE_ERROR3(status,op,txt)	\
+	throw Error(status, op, txt, string(), 0)
+
 #endif
+
+#define PJSUA2_CHECK_RAISE_ERROR2(status, op)	\
+	do { \
+	    if (status != PJ_SUCCESS) \
+		PJSUA2_RAISE_ERROR2(status, op); \
+	} while (0)
+
+#define PJSUA2_CHECK_RAISE_ERROR(status)	\
+	PJSUA2_CHECK_RAISE_ERROR2(status, "")
+
 
 //////////////////////////////////////////////////////////////////////////////
@@ -182,535 +200,16 @@
 
     /** Permanent subscriber key. */
-    string	aka_k;
+    string	akaK;
 
     /** Operator variant key. */
-    string	aka_op;
+    string	akaOp;
 
     /** Authentication Management Field	*/
-    string	aka_amf;
-
-    /**
-     * Default constructor.
-     */
-    AuthCredInfo();
+    string	akaAmf;
+
 };
 
 /** Array of SIP credentials */
 typedef std::vector<AuthCredInfo> AuthCredInfoVector;
-
-//////////////////////////////////////////////////////////////////////////////
-
-struct UaConfig
-{
-    /**
-     * Maximum calls to support (default: 4). The value specified here
-     * must be smaller than the compile time maximum settings
-     * PJSUA_MAX_CALLS, which by default is 32. To increase this
-     * limit, the library must be recompiled with new PJSUA_MAX_CALLS
-     * value.
-     */
-    unsigned		maxCalls;
-
-    /**
-     * Number of worker threads. Normally application will want to have at
-     * least one worker thread, unless when it wants to poll the library
-     * periodically, which in this case the worker thread can be set to
-     * zero.
-     */
-    unsigned		threadCnt;
-
-    /**
-     * Array of nameservers to be used by the SIP resolver subsystem.
-     * The order of the name server specifies the priority (first name
-     * server will be used first, unless it is not reachable).
-     */
-    StringVector	nameserver;
-
-    /**
-     * Optional user agent string (default empty). If it's empty, no
-     * User-Agent header will be sent with outgoing requests.
-     */
-    string		userAgent;
-
-    /**
-     * Array of STUN servers to try. The library will try to resolve and
-     * contact each of the STUN server entry until it finds one that is
-     * usable. Each entry may be a domain name, host name, IP address, and
-     * it may contain an optional port number. For example:
-     *	- "pjsip.org" (domain name)
-     *	- "sip.pjsip.org" (host name)
-     *	- "pjsip.org:33478" (domain name and a non-standard port number)
-     *	- "10.0.0.1:3478" (IP address and port number)
-     *
-     * When nameserver is configured in the \a pjsua_config.nameserver field,
-     * if entry is not an IP address, it will be resolved with DNS SRV
-     * resolution first, and it will fallback to use DNS A resolution if this
-     * fails. Port number may be specified even if the entry is a domain name,
-     * in case the DNS SRV resolution should fallback to a non-standard port.
-     *
-     * When nameserver is not configured, entries will be resolved with
-     * #pj_gethostbyname() if it's not an IP address. Port number may be
-     * specified if the server is not listening in standard STUN port.
-     */
-    StringVector	stunServer;
-
-    /**
-     * This specifies if the library startup should ignore failure with the
-     * STUN servers. If this is set to PJ_FALSE, the library will refuse to
-     * start if it fails to resolve or contact any of the STUN servers.
-     *
-     * Default: TRUE
-     */
-    bool		stunIgnoreFailure;
-
-    /**
-     * Support for adding and parsing NAT type in the SDP to assist
-     * troubleshooting. The valid values are:
-     *	- 0: no information will be added in SDP, and parsing is disabled.
-     *	- 1: only the NAT type number is added.
-     *	- 2: add both NAT type number and name.
-     *
-     * Default: 1
-     */
-    int			natTypeInSdp;
-
-    /**
-     * Handle unsolicited NOTIFY requests containing message waiting
-     * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests
-     * which are not requested by client with SUBSCRIBE request.
-     *
-     * If this is enabled, the library will respond 200/OK to the NOTIFY
-     * request and forward the request to EpCallback.onMwiInfo() callback.
-     *
-     * See also AccountMwiConfig.enabled.
-     *
-     * Default: PJ_TRUE
-     */
-    bool	    	mwiUnsolicitedEnabled;
-
-public:
-    /**
-     * Default constructor to initialize with default values.
-     */
-    UaConfig();
-
-    /**
-     * Construct from pjsua_config.
-     */
-    void fromPj(const pjsua_config &ua_cfg);
-
-    /**
-     * Export to pjsua_config
-     */
-    pjsua_config toPj() const;
-};
-
-
-/**
- * Data containing log entry to be written by the LogWriter.
- */
-struct LogEntry
-{
-    /** Log verbosity level of this message */
-    int		level;
-
-    /** The log message */
-    string	msg;
-
-    /** ID of current thread */
-    long	threadId;
-
-    /** The name of the thread that writes this log */
-    string	threadName;
-};
-
-
-/**
- * Interface for writing log messages. Applications can inherit this class
- * and supply it in the LogConfig structure to implement custom log
- * writing facility.
- */
-class LogWriter
-{
-public:
-    /** Destructor */
-    virtual ~LogWriter() {}
-
-    /** Write a log entry. */
-    virtual void write(const LogEntry &entry) = 0;
-};
-
-
-/**
- * Logging configuration, which can be (optionally) specified when calling
- * Lib::init().
- */
-struct LogConfig
-{
-    /** Log incoming and outgoing SIP message? Yes!  */
-    unsigned		msgLogging;
-
-    /** Input verbosity level. Value 5 is reasonable. */
-    unsigned		level;
-
-    /** Verbosity level for console. Value 4 is reasonable. */
-    unsigned		consoleLevel;
-
-    /** Log decoration. */
-    unsigned		decor;
-
-    /** Optional log filename if app wishes the library to write to log file.
-     */
-    string		filename;
-
-    /**
-     * Additional flags to be given to #pj_file_open() when opening
-     * the log file. By default, the flag is PJ_O_WRONLY. Application
-     * may set PJ_O_APPEND here so that logs are appended to existing
-     * file instead of overwriting it.
-     *
-     * Default is 0.
-     */
-    unsigned		fileFlags;
-
-    /**
-     * Custom log writer, if required. If specified, the instance of LogWriter
-     * must be kept alive througout the duration of the application.
-     */
-    LogWriter		*writer;
-
-public:
-    /** Default constructor initialises with default values */
-    LogConfig();
-
-    /** Construct from pjsua_logging_config */
-    void fromPj(const pjsua_logging_config &lc);
-
-    /** Generate pjsua_logging_config. */
-    pjsua_logging_config toPj() const;
-};
-
-
-/**
- * This structure describes media configuration, which will be specified
- * when calling Lib::init().
- */
-struct MediaConfig
-{
-public:
-    /**
-     * Clock rate to be applied to the conference bridge.
-     * If value is zero, default clock rate will be used
-     * (PJSUA_DEFAULT_CLOCK_RATE, which by default is 16KHz).
-     */
-    unsigned		clockRate;
-
-    /**
-     * Clock rate to be applied when opening the sound device.
-     * If value is zero, conference bridge clock rate will be used.
-     */
-    unsigned		sndClockRate;
-
-    /**
-     * Channel count be applied when opening the sound device and
-     * conference bridge.
-     */
-    unsigned		channelCount;
-
-    /**
-     * Specify audio frame ptime. The value here will affect the
-     * samples per frame of both the sound device and the conference
-     * bridge. Specifying lower ptime will normally reduce the
-     * latency.
-     *
-     * Default value: PJSUA_DEFAULT_AUDIO_FRAME_PTIME
-     */
-    unsigned		audioFramePtime;
-
-    /**
-     * Specify maximum number of media ports to be created in the
-     * conference bridge. Since all media terminate in the bridge
-     * (calls, file player, file recorder, etc), the value must be
-     * large enough to support all of them. However, the larger
-     * the value, the more computations are performed.
-     *
-     * Default value: PJSUA_MAX_CONF_PORTS
-     */
-    unsigned		maxMediaPorts;
-
-    /**
-     * Specify whether the media manager should manage its own
-     * ioqueue for the RTP/RTCP sockets. If yes, ioqueue will be created
-     * and at least one worker thread will be created too. If no,
-     * the RTP/RTCP sockets will share the same ioqueue as SIP sockets,
-     * and no worker thread is needed.
-     *
-     * Normally application would say yes here, unless it wants to
-     * run everything from a single thread.
-     */
-    bool		hasIoqueue;
-
-    /**
-     * Specify the number of worker threads to handle incoming RTP
-     * packets. A value of one is recommended for most applications.
-     */
-    unsigned		threadCnt;
-
-    /**
-     * Media quality, 0-10, according to this table:
-     *   5-10: resampling use large filter,
-     *   3-4:  resampling use small filter,
-     *   1-2:  resampling use linear.
-     * The media quality also sets speex codec quality/complexity to the
-     * number.
-     *
-     * Default: 5 (PJSUA_DEFAULT_CODEC_QUALITY).
-     */
-    unsigned		quality;
-
-    /**
-     * Specify default codec ptime.
-     *
-     * Default: 0 (codec specific)
-     */
-    unsigned		ptime;
-
-    /**
-     * Disable VAD?
-     *
-     * Default: 0 (no (meaning VAD is enabled))
-     */
-    bool		noVad;
-
-    /**
-     * iLBC mode (20 or 30).
-     *
-     * Default: 30 (PJSUA_DEFAULT_ILBC_MODE)
-     */
-    unsigned		ilbcMode;
-
-    /**
-     * Percentage of RTP packet to drop in TX direction
-     * (to simulate packet lost).
-     *
-     * Default: 0
-     */
-    unsigned		txDropPct;
-
-    /**
-     * Percentage of RTP packet to drop in RX direction
-     * (to simulate packet lost).
-     *
-     * Default: 0
-     */
-    unsigned		rxDropPct;
-
-    /**
-     * Echo canceller options (see #pjmedia_echo_create())
-     *
-     * Default: 0.
-     */
-    unsigned		ecOptions;
-
-    /**
-     * Echo canceller tail length, in miliseconds. Setting this to zero
-     * will disable echo cancellation.
-     *
-     * Default: PJSUA_DEFAULT_EC_TAIL_LEN
-     */
-    unsigned		ecTailLen;
-
-    /**
-     * Audio capture buffer length, in milliseconds.
-     *
-     * Default: PJMEDIA_SND_DEFAULT_REC_LATENCY
-     */
-    unsigned		sndRecLatency;
-
-    /**
-     * Audio playback buffer length, in milliseconds.
-     *
-     * Default: PJMEDIA_SND_DEFAULT_PLAY_LATENCY
-     */
-    unsigned		sndPlayLatency;
-
-    /**
-     * Jitter buffer initial prefetch delay in msec. The value must be
-     * between jb_min_pre and jb_max_pre below.
-     *
-     * Default: -1 (to use default stream settings, currently 150 msec)
-     */
-    int			jbInit;
-
-    /**
-     * Jitter buffer minimum prefetch delay in msec.
-     *
-     * Default: -1 (to use default stream settings, currently 60 msec)
-     */
-    int			jbMinPre;
-
-    /**
-     * Jitter buffer maximum prefetch delay in msec.
-     *
-     * Default: -1 (to use default stream settings, currently 240 msec)
-     */
-    int			jbMaxPre;
-
-    /**
-     * Set maximum delay that can be accomodated by the jitter buffer msec.
-     *
-     * Default: -1 (to use default stream settings, currently 360 msec)
-     */
-    int			jbMax;
-
-    /**
-     * Specify idle time of sound device before it is automatically closed,
-     * in seconds. Use value -1 to disable the auto-close feature of sound
-     * device
-     *
-     * Default : 1
-     */
-    int			sndAutoCloseTime;
-
-    /**
-     * Specify whether built-in/native preview should be used if available.
-     * In some systems, video input devices have built-in capability to show
-     * preview window of the device. Using this built-in preview is preferable
-     * as it consumes less CPU power. If built-in preview is not available,
-     * the library will perform software rendering of the input. If this
-     * field is set to PJ_FALSE, software preview will always be used.
-     *
-     * Default: PJ_TRUE
-     */
-    bool		vidPreviewEnableNative;
-
-public:
-    /** Default constructor initialises with default values */
-    MediaConfig();
-
-    /** Construct from pjsua_media_config. */
-    void fromPj(const pjsua_media_config &mc);
-
-    /** Export */
-    pjsua_media_config toPj() const;
-};
-
-
-/**
- * Endpoint configuration
- */
-struct EpConfig
-{
-    /** UA config */
-    UaConfig		uaConfig;
-
-    /** Logging config */
-    LogConfig		logConfig;
-
-    /** Media config */
-    MediaConfig		medConfig;
-};
-
-
-//////////////////////////////////////////////////////////////////////////////
-
-/**
- * Argument to EpCallback::onNatDetectionComplete() callback.
- */
-struct NatDetectionCompleteParam
-{
-    /**
-     * Status of the detection process. If this value is not PJ_SUCCESS,
-     * the detection has failed and \a nat_type field will contain
-     * PJ_STUN_NAT_TYPE_UNKNOWN.
-     */
-    pj_status_t		status;
-
-    /**
-     * The text describing the status, if the status is not PJ_SUCCESS.
-     */
-    string		reason;
-
-    /**
-     * This contains the NAT type as detected by the detection procedure.
-     * This value is only valid when the \a status is PJ_SUCCESS.
-     */
-    pj_stun_nat_type	natType;
-
-    /**
-     * Text describing that NAT type.
-     */
-    string		natTypeName;
-
-};
-
-/**
- * Argument to EpCallback::onNatCheckStunServersComplete() callback.
- */
-struct NatCheckStunServersCompleteParam
-{
-    /**
-     * Arbitrary user data that was passed to Endpoint::natCheckStunServers()
-     * function.
-     */
-    Token		userData;
-
-    /**
-     * This will contain PJ_SUCCESS if at least one usable STUN server
-     * is found, otherwise it will contain the last error code during
-     * the operation.
-     */
-    pj_status_t		status;
-
-    /**
-     * The server name that yields successful result. This will only
-     * contain value if status is successful.
-     */
-    string		name;
-
-    /**
-     * The server IP address and port in "IP:port" format. This will only
-     * contain value if status is successful.
-     */
-    SocketAddress	addr;
-};
-
-/**
- * Parameter of EpCallback::OnTimerComplete() callback.
- */
-struct TimerCompleteParam
-{
-    /**
-     * Arbitrary user data that was passed to Endpoint::utilTimerSchedule()
-     * function.
-     */
-    Token		userData;
-
-    /**
-     * The interval of this timer, in miliseconds.
-     */
-    unsigned		msecDelay;
-};
-
-/**
- * Parameter of EpCallback::onTransportStateChanged() callback.
- */
-struct TransportStateChangedParam
-{
-    /**
-     * The transport handle.
-     */
-    TransportHandle	hnd;
-
-    /**
-     * Transport current state.
-     */
-    pjsip_transport_state state;
-
-    /**
-     * The last error code related to the transport state.
-     */
-    pj_status_t		lastError;
-};
 
 //////////////////////////////////////////////////////////////////////////////
@@ -866,4 +365,13 @@
 
     /**
+     * Specify the port range for socket binding, relative to the start
+     * port number specified in \a port. Note that this setting is only
+     * applicable when the start port number is non zero.
+     *
+     * Default value is zero.
+     */
+    unsigned		portRange;
+
+    /**
      * Optional address to advertise as the address of this transport.
      * Application can specify any address or hostname for this field,
@@ -960,4 +468,157 @@
 };
 
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This structure describes an incoming SIP message. It corresponds to the
+ * pjsip_rx_data structure in PJSIP library.
+ */
+struct SipRxData
+{
+    /**
+     * A short info string describing the request, which normally contains
+     * the request method and its CSeq.
+     */
+    string		info;
+
+    /**
+     * The whole message data as a string, containing both the header section
+     * and message body section.
+     */
+    string		wholeMsg;
+
+    /**
+     * Source IP address of the message.
+     */
+    string		srcIp;
+
+    /**
+     * Source port number of the message.
+     */
+    unsigned		srcPort;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * SIP media type containing type and subtype. For example, for
+ * "application/sdp", the type is "application" and the subtype is "sdp".
+ */
+struct SipMediaType
+{
+    /** Media type. */
+    string		type;
+
+    /** Media subtype. */
+    string		subType;
+};
+
+/**
+ * Simple SIP header.
+ */
+struct SipHeader
+{
+    /**
+     * Header name.
+     */
+    string		hName;
+
+    /**
+     * Header value.
+     */
+    string		hValue;
+
+    /**
+     * Initiaize from PJSIP header.
+     */
+    void fromPj(const pjsip_hdr *) throw(Error);
+
+    /**
+     * Convert to PJSIP header.
+     */
+    pjsip_generic_string_hdr &toPj() const;
+
+private:
+    /** Interal buffer for conversion to PJSIP header */
+    mutable pjsip_generic_string_hdr	pjHdr;
+};
+
+
+/** Array of strings */
+typedef std::vector<SipHeader> SipHeaderVector;
+
+/**
+ * This describes each multipart part.
+ */
+struct SipMultipartPart
+{
+    /**
+     * Optional headers to be put in this multipart part.
+     */
+    SipHeaderVector	headers;
+
+    /**
+     * The MIME type of the body part of this multipart part.
+     */
+    SipMediaType	contentType;
+
+    /**
+     * The body part of tthis multipart part.
+     */
+    string		body;
+};
+
+/** Array of multipart parts */
+typedef std::vector<SipMultipartPart> SipMultipartPartVector;
+
+/**
+ * Additional options when sending outgoing SIP message. This corresponds to
+ * pjsua_msg_data structure in PJSIP library.
+ */
+struct SipTxOption
+{
+    /**
+     * Optional remote target URI (i.e. Target header). If NULL, the target
+     * will be set to the remote URI (To header). At the moment this field
+     * is only used when sending initial INVITE and MESSAGE requests.
+     */
+    string		targetUri;
+
+    /**
+     * Additional message headers to be included in the outgoing message.
+     */
+    SipHeaderVector	headers;
+
+    /**
+     * MIME type of the message body, if application specifies the messageBody
+     * in this structure.
+     */
+    string		contentType;
+
+    /**
+     * Optional message body to be added to the message, only when the
+     * message doesn't have a body.
+     */
+    string		msgBody;
+
+    /**
+     * Content type of the multipart body. If application wants to send
+     * multipart message bodies, it puts the parts in multipartParts and set
+     * the content type in multipartContentType. If the message already
+     * contains a body, the body will be added to the multipart bodies.
+     */
+    SipMediaType	multipartContentType;
+
+    /**
+     * Array of multipart parts. If application wants to send multipart
+     * message bodies, it puts the parts in \a parts and set the content
+     * type in \a multipart_ctype. If the message already contains a body,
+     * the body will be added to the multipart bodies.
+     */
+    SipMultipartPartVector	multipartParts;
+
+};
+
 
 } // namespace pj
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/account.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/account.cpp	(revision 4608)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/account.cpp	(revision 4608)
@@ -0,0 +1,332 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 <pjsua2/account.hpp>
+#include <pj/ctype.h>
+#include "util.hpp"
+
+using namespace pj;
+using namespace std;
+
+#define THIS_FILE		"account.cpp"
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+AccountConfig::AccountConfig()
+{
+    pjsua_acc_config acc_cfg;
+    pjsua_acc_config_default(&acc_cfg);
+    pjsua_media_config med_cfg;
+    pjsua_media_config_default(&med_cfg);
+    fromPj(acc_cfg, &med_cfg);
+}
+
+/* Convert to pjsip. */
+pjsua_acc_config AccountConfig::toPj() const
+{
+    pjsua_acc_config ret;
+    unsigned i;
+
+    pjsua_acc_config_default(&ret);
+
+    // Global
+    ret.priority		= priority;
+    ret.id			= str2Pj(idUri);
+
+    // AccountRegConfig
+    ret.reg_uri			= str2Pj(regConfig.registrarUri);
+    ret.register_on_acc_add	= regConfig.registerOnAdd;
+    ret.reg_timeout		= regConfig.timeoutSec;
+    ret.reg_retry_interval	= regConfig.retryIntervalSec;
+    ret.reg_first_retry_interval= regConfig.firstRetryIntervalSec;
+    ret.reg_delay_before_refresh= regConfig.delayBeforeRefreshSec;
+    ret.drop_calls_on_reg_fail	= regConfig.dropCallsOnFail;
+    ret.unreg_timeout		= regConfig.unregWaitSec;
+    ret.reg_use_proxy		= regConfig.proxyUse;
+    for (i=0; i<regConfig.headers.size(); ++i) {
+	pj_list_push_back(&ret.reg_hdr_list, &regConfig.headers[i].toPj());
+    }
+
+    // AccountSipConfig
+    ret.cred_count = 0;
+    if (sipConfig.authCreds.size() > PJ_ARRAY_SIZE(ret.cred_info))
+	PJSUA2_RAISE_ERROR(PJ_ETOOMANY);
+    for (i=0; i<sipConfig.authCreds.size(); ++i) {
+	const AuthCredInfo &src = sipConfig.authCreds[i];
+	pjsip_cred_info *dst = &ret.cred_info[i];
+
+	dst->realm	= str2Pj(src.realm);
+	dst->scheme	= str2Pj(src.scheme);
+	dst->username	= str2Pj(src.username);
+	dst->data_type	= src.dataType;
+	dst->data	= str2Pj(src.data);
+	dst->ext.aka.k	= str2Pj(src.akaK);
+	dst->ext.aka.op	= str2Pj(src.akaOp);
+	dst->ext.aka.amf= str2Pj(src.akaAmf);
+
+	ret.cred_count++;
+    }
+    ret.proxy_cnt = 0;
+    if (sipConfig.proxies.size() > PJ_ARRAY_SIZE(ret.proxy))
+	PJSUA2_RAISE_ERROR(PJ_ETOOMANY);
+    for (i=0; i<sipConfig.proxies.size(); ++i) {
+	ret.proxy[ret.proxy_cnt++] = str2Pj(sipConfig.proxies[i]);
+    }
+    ret.force_contact		= str2Pj(sipConfig.contactForced);
+    ret.contact_params		= str2Pj(sipConfig.contactParams);
+    ret.contact_uri_params	= str2Pj(sipConfig.contactUriParams);
+    ret.auth_pref.initial_auth	= sipConfig.authInitialEmpty;
+    ret.auth_pref.algorithm	= str2Pj(sipConfig.authInitialAlgorithm);
+    ret.transport_id		= sipConfig.transportId;
+
+    // AccountCallConfig
+    ret.call_hold_type		= callConfig.holdType;
+    ret.require_100rel		= callConfig.prackUse;
+    ret.use_timer		= callConfig.timerUse;
+    ret.timer_setting.min_se	= callConfig.timerMinSESec;
+    ret.timer_setting.sess_expires = callConfig.timerSessExpiresSec;
+
+    // AccountPresConfig
+    for (i=0; i<presConfig.headers.size(); ++i) {
+	pj_list_push_back(&ret.sub_hdr_list, &presConfig.headers[i].toPj());
+    }
+    ret.publish_enabled		= presConfig.publishEnabled;
+    ret.publish_opt.queue_request= presConfig.publishQueue;
+    ret.unpublish_max_wait_time_msec = presConfig.publishShutdownWaitMsec;
+    ret.pidf_tuple_id		= str2Pj(presConfig.pidfTupleId);
+
+    // AccountNatConfig
+    ret.sip_stun_use		= natConfig.sipStunUse;
+    ret.media_stun_use		= natConfig.mediaStunUse;
+    ret.ice_cfg_use		= PJSUA_ICE_CONFIG_USE_CUSTOM;
+    ret.ice_cfg.enable_ice	= natConfig.iceEnabled;
+    ret.ice_cfg.ice_max_host_cands = natConfig.iceMaxHostCands;
+    ret.ice_cfg.ice_opt.aggressive = natConfig.iceAggressiveNomination;
+    ret.ice_cfg.ice_opt.nominated_check_delay = natConfig.iceNominatedCheckDelayMsec;
+    ret.ice_cfg.ice_opt.controlled_agent_want_nom_timeout = natConfig.iceWaitNominationTimeoutMsec;
+    ret.ice_cfg.ice_no_rtcp	= natConfig.iceNoRtcp;
+    ret.ice_cfg.ice_always_update = natConfig.iceAlwaysUpdate;
+
+    ret.turn_cfg_use 		= PJSUA_TURN_CONFIG_USE_CUSTOM;
+    ret.turn_cfg.enable_turn	= natConfig.turnEnabled;
+    ret.turn_cfg.turn_server	= str2Pj(natConfig.turnServer);
+    ret.turn_cfg.turn_conn_type	= natConfig.turnConnType;
+    ret.turn_cfg.turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+    ret.turn_cfg.turn_auth_cred.data.static_cred.username = str2Pj(natConfig.turnUserName);
+    ret.turn_cfg.turn_auth_cred.data.static_cred.data_type = (pj_stun_passwd_type)natConfig.turnPasswordType;
+    ret.turn_cfg.turn_auth_cred.data.static_cred.data = str2Pj(natConfig.turnPassword);
+    ret.turn_cfg.turn_auth_cred.data.static_cred.realm = pj_str((char*)"");
+    ret.turn_cfg.turn_auth_cred.data.static_cred.nonce = pj_str((char*)"");
+
+    ret.allow_contact_rewrite	= natConfig.contactRewriteUse;
+    ret.contact_rewrite_method	= natConfig.contactRewriteMethod;
+    ret.allow_via_rewrite	= natConfig.viaRewriteUse;
+    ret.allow_sdp_nat_rewrite	= natConfig.sdpNatRewriteUse;
+    ret.use_rfc5626		= natConfig.sipOutboundUse;
+    ret.rfc5626_instance_id	= str2Pj(natConfig.sipOutboundInstanceId);
+    ret.rfc5626_reg_id		= str2Pj(natConfig.sipOutboundRegId);
+    ret.ka_interval		= natConfig.udpKaIntervalSec;
+    ret.ka_data			= str2Pj(natConfig.udpKaData);
+
+    // AccountMediaConfig
+    ret.rtp_cfg			= mediaConfig.transportConfig.toPj();
+    ret.lock_codec		= mediaConfig.lockCodecEnabled;
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0)
+    ret.use_stream_ka		= mediaConfig.streamKaEnabled;
+#endif
+    ret.use_srtp		= mediaConfig.srtpUse;
+    ret.srtp_secure_signaling	= mediaConfig.srtpSecureSignaling;
+    ret.ipv6_media_use		= mediaConfig.ipv6Use;
+
+    // AccountVideoConfig
+    ret.vid_in_auto_show	= videoConfig.autoShowIncoming;
+    ret.vid_out_auto_transmit	= videoConfig.autoTransmitOutgoing;
+    ret.vid_wnd_flags		= videoConfig.windowFlags;
+    ret.vid_cap_dev		= videoConfig.defaultCaptureDevice;
+    ret.vid_rend_dev		= videoConfig.defaultRenderDevice;
+    ret.vid_stream_rc_cfg.method= videoConfig.rateControlMethod;
+    ret.vid_stream_rc_cfg.bandwidth = videoConfig.rateControlBandwidth;
+
+    return ret;
+}
+
+/* Initialize from pjsip. */
+void AccountConfig::fromPj(const pjsua_acc_config &prm,
+                           const pjsua_media_config *mcfg)
+{
+    const pjsip_hdr *hdr;
+    unsigned i;
+
+    // Global
+    priority			= prm.priority;
+    idUri			= pj2Str(prm.id);
+
+    // AccountRegConfig
+    regConfig.registrarUri	= pj2Str(prm.reg_uri);
+    regConfig.registerOnAdd	= (prm.register_on_acc_add != 0);
+    regConfig.timeoutSec	= prm.reg_timeout;
+    regConfig.retryIntervalSec	= prm.reg_retry_interval;
+    regConfig.firstRetryIntervalSec = prm.reg_first_retry_interval;
+    regConfig.delayBeforeRefreshSec = prm.reg_delay_before_refresh;
+    regConfig.dropCallsOnFail	= prm.drop_calls_on_reg_fail;
+    regConfig.unregWaitSec	= prm.unreg_timeout;
+    regConfig.proxyUse		= prm.reg_use_proxy;
+    regConfig.headers.clear();
+    hdr = prm.reg_hdr_list.next;
+    while (hdr != &prm.reg_hdr_list) {
+	SipHeader new_hdr;
+	new_hdr.fromPj(hdr);
+
+	regConfig.headers.push_back(new_hdr);
+
+	hdr = hdr->next;
+    }
+
+    // AccountSipConfig
+    sipConfig.authCreds.clear();
+    for (i=0; i<prm.cred_count; ++i) {
+	AuthCredInfo cred;
+	const pjsip_cred_info &src = prm.cred_info[i];
+
+	cred.realm	= pj2Str(src.realm);
+	cred.scheme	= pj2Str(src.scheme);
+	cred.username	= pj2Str(src.username);
+	cred.dataType	= src.data_type;
+	cred.data	= pj2Str(src.data);
+	cred.akaK	= pj2Str(src.ext.aka.k);
+	cred.akaOp	= pj2Str(src.ext.aka.op);
+	cred.akaAmf	= pj2Str(src.ext.aka.amf);
+
+	sipConfig.authCreds.push_back(cred);
+    }
+    sipConfig.proxies.clear();
+    for (i=0; i<prm.proxy_cnt; ++i) {
+	sipConfig.proxies.push_back(pj2Str(prm.proxy[i]));
+    }
+    sipConfig.contactForced	= pj2Str(prm.force_contact);
+    sipConfig.contactParams	= pj2Str(prm.contact_params);
+    sipConfig.contactUriParams	= pj2Str(prm.contact_uri_params);
+    sipConfig.authInitialEmpty	= prm.auth_pref.initial_auth;
+    sipConfig.authInitialAlgorithm = pj2Str(prm.auth_pref.algorithm);
+    sipConfig.transportId	= prm.transport_id;
+
+    // AccountCallConfig
+    callConfig.holdType		= prm.call_hold_type;
+    callConfig.prackUse		= prm.require_100rel;
+    callConfig.timerUse		= prm.use_timer;
+    callConfig.timerMinSESec	= prm.timer_setting.min_se;
+    callConfig.timerSessExpiresSec = prm.timer_setting.sess_expires;
+
+    // AccountPresConfig
+    presConfig.headers.clear();
+    hdr = prm.sub_hdr_list.next;
+    while (hdr != &prm.sub_hdr_list) {
+	SipHeader new_hdr;
+	new_hdr.fromPj(hdr);
+	presConfig.headers.push_back(new_hdr);
+	hdr = hdr->next;
+    }
+    presConfig.publishEnabled	= prm.publish_enabled;
+    presConfig.publishQueue	= prm.publish_opt.queue_request;
+    presConfig.publishShutdownWaitMsec = prm.unpublish_max_wait_time_msec;
+    presConfig.pidfTupleId	= pj2Str(prm.pidf_tuple_id);
+
+    // AccountMwiConfig
+    mwiConfig.enabled		= prm.mwi_enabled;
+    mwiConfig.expirationSec	= prm.mwi_expires;
+
+    // AccountNatConfig
+    natConfig.sipStunUse	= prm.sip_stun_use;
+    natConfig.mediaStunUse	= prm.media_stun_use;
+    if (prm.ice_cfg_use == PJSUA_ICE_CONFIG_USE_CUSTOM) {
+	natConfig.iceEnabled = prm.ice_cfg.enable_ice;
+	natConfig.iceMaxHostCands = prm.ice_cfg.ice_max_host_cands;
+	natConfig.iceAggressiveNomination = prm.ice_cfg.ice_opt.aggressive;
+	natConfig.iceNominatedCheckDelayMsec = prm.ice_cfg.ice_opt.nominated_check_delay;
+	natConfig.iceWaitNominationTimeoutMsec = prm.ice_cfg.ice_opt.controlled_agent_want_nom_timeout;
+	natConfig.iceNoRtcp	= prm.ice_cfg.ice_no_rtcp;
+	natConfig.iceAlwaysUpdate = prm.ice_cfg.ice_always_update;
+    } else {
+	pjsua_media_config default_mcfg;
+	if (!mcfg) {
+	    pjsua_media_config_default(&default_mcfg);
+	    mcfg = &default_mcfg;
+	}
+	natConfig.iceEnabled	= mcfg->enable_ice;
+	natConfig.iceMaxHostCands= mcfg->ice_max_host_cands;
+	natConfig.iceAggressiveNomination = mcfg->ice_opt.aggressive;
+	natConfig.iceNominatedCheckDelayMsec = mcfg->ice_opt.nominated_check_delay;
+	natConfig.iceWaitNominationTimeoutMsec = mcfg->ice_opt.controlled_agent_want_nom_timeout;
+	natConfig.iceNoRtcp	= mcfg->ice_no_rtcp;
+	natConfig.iceAlwaysUpdate = mcfg->ice_always_update;
+    }
+
+    if (prm.turn_cfg_use == PJSUA_TURN_CONFIG_USE_CUSTOM) {
+	natConfig.turnEnabled	= prm.turn_cfg.enable_turn;
+	natConfig.turnServer	= pj2Str(prm.turn_cfg.turn_server);
+	natConfig.turnConnType	= prm.turn_cfg.turn_conn_type;
+	natConfig.turnUserName	= pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.username);
+	natConfig.turnPasswordType = prm.turn_cfg.turn_auth_cred.data.static_cred.data_type;
+	natConfig.turnPassword	= pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.data);
+    } else {
+	pjsua_media_config default_mcfg;
+	if (!mcfg) {
+	    pjsua_media_config_default(&default_mcfg);
+	    mcfg = &default_mcfg;
+	}
+	natConfig.turnEnabled	= mcfg->enable_turn;
+	natConfig.turnServer	= pj2Str(mcfg->turn_server);
+	natConfig.turnConnType	= mcfg->turn_conn_type;
+	natConfig.turnUserName	= pj2Str(mcfg->turn_auth_cred.data.static_cred.username);
+	natConfig.turnPasswordType = mcfg->turn_auth_cred.data.static_cred.data_type;
+	natConfig.turnPassword	= pj2Str(mcfg->turn_auth_cred.data.static_cred.data);
+    }
+    natConfig.contactRewriteUse	= prm.allow_contact_rewrite;
+    natConfig.contactRewriteMethod = prm.contact_rewrite_method;
+    natConfig.viaRewriteUse	= prm.allow_via_rewrite;
+    natConfig.sdpNatRewriteUse	= prm.allow_sdp_nat_rewrite;
+    natConfig.sipOutboundUse	= prm.use_rfc5626;
+    natConfig.sipOutboundInstanceId = pj2Str(prm.rfc5626_instance_id);
+    natConfig.sipOutboundRegId	= pj2Str(prm.rfc5626_reg_id);
+    natConfig.udpKaIntervalSec	= prm.ka_interval;
+    natConfig.udpKaData		= pj2Str(prm.ka_data);
+
+    // AccountMediaConfig
+    mediaConfig.transportConfig.fromPj(prm.rtp_cfg);
+    mediaConfig.lockCodecEnabled= prm.lock_codec;
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0)
+    mediaConfig.streamKaEnabled	= prm.use_stream_ka;
+#else
+    mediaConfig.streamKaEnabled	= false;
+#endif
+    mediaConfig.srtpUse		= prm.use_srtp;
+    mediaConfig.srtpSecureSignaling = prm.srtp_secure_signaling;
+    mediaConfig.ipv6Use		= prm.ipv6_media_use;
+
+    // AccountVideoConfig
+    videoConfig.autoShowIncoming 	= prm.vid_in_auto_show;
+    videoConfig.autoTransmitOutgoing	= prm.vid_out_auto_transmit;
+    videoConfig.windowFlags		= prm.vid_wnd_flags;
+    videoConfig.defaultCaptureDevice	= prm.vid_cap_dev;
+    videoConfig.defaultRenderDevice	= prm.vid_rend_dev;
+    videoConfig.rateControlMethod	= prm.vid_stream_rc_cfg.method;
+    videoConfig.rateControlBandwidth	= prm.vid_stream_rc_cfg.bandwidth;
+}
+
+
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4608)
@@ -18,4 +18,5 @@
  */
 #include <pjsua2/endpoint.hpp>
+#include "util.hpp"
 
 using namespace pj;
@@ -29,5 +30,5 @@
 {
     pj_uint32_t		signature;
-    TimerCompleteParam	prm;
+    OnTimerParam	prm;
     pj_timer_entry	entry;
 };
@@ -35,4 +36,174 @@
 
 ///////////////////////////////////////////////////////////////////////////////
+
+UaConfig::UaConfig()
+{
+    pjsua_config ua_cfg;
+
+    pjsua_config_default(&ua_cfg);
+    fromPj(ua_cfg);
+}
+
+void UaConfig::fromPj(const pjsua_config &ua_cfg)
+{
+    unsigned i;
+
+    this->maxCalls = ua_cfg.max_calls;
+    this->threadCnt = ua_cfg.thread_cnt;
+    this->userAgent = pj2Str(ua_cfg.user_agent);
+
+    for (i=0; i<ua_cfg.nameserver_count; ++i) {
+	this->nameserver.push_back(pj2Str(ua_cfg.nameserver[i]));
+    }
+
+    for (i=0; i<ua_cfg.stun_srv_cnt; ++i) {
+	this->stunServer.push_back(pj2Str(ua_cfg.stun_srv[i]));
+    }
+
+    this->stunIgnoreFailure = ua_cfg.stun_ignore_failure;
+    this->natTypeInSdp = ua_cfg.nat_type_in_sdp;
+    this->mwiUnsolicitedEnabled = ua_cfg.enable_unsolicited_mwi;
+}
+
+pjsua_config UaConfig::toPj() const
+{
+    unsigned i;
+    pjsua_config pua_cfg;
+
+    pjsua_config_default(&pua_cfg);
+
+    pua_cfg.max_calls = this->maxCalls;
+    pua_cfg.thread_cnt = this->threadCnt;
+    pua_cfg.user_agent = str2Pj(this->userAgent);
+
+    for (i=0; i<this->nameserver.size() && i<PJ_ARRAY_SIZE(pua_cfg.nameserver);
+	 ++i)
+    {
+	pua_cfg.nameserver[i] = str2Pj(this->nameserver[i]);
+    }
+    pua_cfg.nameserver_count = i;
+
+    for (i=0; i<this->stunServer.size() && i<PJ_ARRAY_SIZE(pua_cfg.stun_srv);
+	 ++i)
+    {
+	pua_cfg.stun_srv[i] = str2Pj(this->stunServer[i]);
+    }
+    pua_cfg.stun_srv_cnt = i;
+
+    pua_cfg.nat_type_in_sdp = this->natTypeInSdp;
+    pua_cfg.enable_unsolicited_mwi = this->mwiUnsolicitedEnabled;
+
+    return pua_cfg;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+LogConfig::LogConfig()
+{
+    pjsua_logging_config lc;
+
+    pjsua_logging_config_default(&lc);
+    fromPj(lc);
+}
+
+void LogConfig::fromPj(const pjsua_logging_config &lc)
+{
+    this->msgLogging = lc.msg_logging;
+    this->level = lc.level;
+    this->consoleLevel = lc.console_level;
+    this->decor = lc.decor;
+    this->filename = pj2Str(lc.log_filename);
+    this->fileFlags = lc.log_file_flags;
+    this->writer = NULL;
+}
+
+pjsua_logging_config LogConfig::toPj() const
+{
+    pjsua_logging_config lc;
+
+    pjsua_logging_config_default(&lc);
+
+    lc.msg_logging = this->msgLogging;
+    lc.level = this->level;
+    lc.console_level = this->consoleLevel;
+    lc.decor = this->decor;
+    lc.log_file_flags = this->fileFlags;
+    lc.log_filename = str2Pj(this->filename);
+
+    return lc;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+MediaConfig::MediaConfig()
+{
+    pjsua_media_config mc;
+
+    pjsua_media_config_default(&mc);
+    fromPj(mc);
+}
+
+void MediaConfig::fromPj(const pjsua_media_config &mc)
+{
+    this->clockRate = mc.clock_rate;
+    this->sndClockRate = mc.snd_clock_rate;
+    this->channelCount = mc.channel_count;
+    this->audioFramePtime = mc.audio_frame_ptime;
+    this->maxMediaPorts = mc.max_media_ports;
+    this->hasIoqueue = mc.has_ioqueue;
+    this->threadCnt = mc.thread_cnt;
+    this->quality = mc.quality;
+    this->ptime = mc.ptime;
+    this->noVad = mc.no_vad;
+    this->ilbcMode = mc.ilbc_mode;
+    this->txDropPct = mc.tx_drop_pct;
+    this->rxDropPct = mc.rx_drop_pct;
+    this->ecOptions = mc.ec_options;
+    this->ecTailLen = mc.ec_tail_len;
+    this->sndRecLatency = mc.snd_rec_latency;
+    this->sndPlayLatency = mc.snd_play_latency;
+    this->jbInit = mc.jb_init;
+    this->jbMinPre = mc.jb_min_pre;
+    this->jbMaxPre = mc.jb_max_pre;
+    this->jbMax = mc.jb_max;
+    this->sndAutoCloseTime = mc.snd_auto_close_time;
+    this->vidPreviewEnableNative = mc.vid_preview_enable_native;
+}
+
+pjsua_media_config MediaConfig::toPj() const
+{
+    pjsua_media_config mcfg;
+
+    pjsua_media_config_default(&mcfg);
+
+    mcfg.clock_rate = this->clockRate;
+    mcfg.snd_clock_rate = this->sndClockRate;
+    mcfg.channel_count = this->channelCount;
+    mcfg.audio_frame_ptime = this->audioFramePtime;
+    mcfg.max_media_ports = this->maxMediaPorts;
+    mcfg.has_ioqueue = this->hasIoqueue;
+    mcfg.thread_cnt = this->threadCnt;
+    mcfg.quality = this->quality;
+    mcfg.ptime = this->ptime;
+    mcfg.no_vad = this->noVad;
+    mcfg.ilbc_mode = this->ilbcMode;
+    mcfg.tx_drop_pct = this->txDropPct;
+    mcfg.rx_drop_pct = this->rxDropPct;
+    mcfg.ec_options = this->ecOptions;
+    mcfg.ec_tail_len = this->ecTailLen;
+    mcfg.snd_rec_latency = this->sndRecLatency;
+    mcfg.snd_play_latency = this->sndPlayLatency;
+    mcfg.jb_init = this->jbInit;
+    mcfg.jb_min_pre = this->jbMinPre;
+    mcfg.jb_max_pre = this->jbMaxPre;
+    mcfg.jb_max = this->jbMax;
+    mcfg.snd_auto_close_time = this->sndAutoCloseTime;
+    mcfg.vid_preview_enable_native = this->vidPreviewEnableNative;
+
+    return mcfg;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
 /*
  * Endpoint instance
@@ -51,5 +222,5 @@
 void Endpoint::testException() throw(Error)
 {
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::testException()", PJ_EINVALIDOP);
+    PJSUA2_CHECK_RAISE_ERROR(PJ_EINVALIDOP);
 }
 
@@ -82,5 +253,5 @@
 	return;
 
-    NatCheckStunServersCompleteParam prm;
+    OnNatCheckStunServersCompleteParam prm;
 
     prm.userData = res->token;
@@ -106,5 +277,5 @@
 	return;
 
-    ep.epCallback->OnTimerComplete(ut->prm);
+    ep.epCallback->onTimer(ut->prm);
 }
 
@@ -116,5 +287,5 @@
 	return;
 
-    NatDetectionCompleteParam prm;
+    OnNatDetectionCompleteParam prm;
 
     prm.status = res->status;
@@ -135,5 +306,5 @@
 	return;
 
-    TransportStateChangedParam prm;
+    OnTransportStateParam prm;
 
     prm.hnd = (TransportHandle)tp;
@@ -141,5 +312,5 @@
     prm.lastError = info ? info->status : PJ_SUCCESS;
 
-    ep.epCallback->onTransportStateChanged(prm);
+    ep.epCallback->onTransportState(prm);
 }
 
@@ -153,5 +324,5 @@
 
     status = pjsua_create();
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libCreate()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -186,5 +357,5 @@
     /* Init! */
     status = pjsua_init(&ua_cfg, &log_cfg, &med_cfg);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libInit()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -194,5 +365,5 @@
 
     status = pjsua_start();
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libStart()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -210,5 +381,5 @@
     }
 
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::libDestroy()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -271,5 +442,5 @@
     if (status != PJ_SUCCESS) {
 	delete ut;
-	PJSUA2_CHECK_RAISE_ERROR("Endpoint::utilTimerSchedule()", status);
+	PJSUA2_CHECK_RAISE_ERROR(status);
     }
 
@@ -302,5 +473,5 @@
 
     status = pj_ssl_cipher_get_availables(ciphers, &count);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::utilSslGetAvailableCiphers()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 
     return IntVector(ciphers, ciphers + count);
@@ -319,5 +490,5 @@
 
     status = pjsua_detect_nat_type();
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natDetectType()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -328,5 +499,5 @@
 
     status = pjsua_get_nat_type(&type);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natGetType()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 
     return type;
@@ -349,5 +520,5 @@
     status = pjsua_resolve_stun_servers(count, srv, wait, token,
     					&Endpoint::stun_resolve_cb);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natCheckStunServers()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -358,5 +529,5 @@
 
     status = pjsua_cancel_stun_resolution(token, notify_cb);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::natCancelCheckStunServers()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -374,5 +545,5 @@
     tcfg = cfg.toPj();
     status = pjsua_transport_create(type, &tcfg, &tid);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportCreate()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 
     return tid;
@@ -386,5 +557,5 @@
 
     status = pjsua_enum_transports(tids, &count);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportEnum()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 
     return IntVector(tids, tids+count);
@@ -397,5 +568,5 @@
 
     status = pjsua_transport_get_info(id, &tinfo);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportGetInfo()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 
     return TransportInfo(tinfo);
@@ -407,5 +578,5 @@
 
     status = pjsua_transport_set_enable(id, enabled);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportSetEnable()", status);
+    PJSUA2_CHECK_RAISE_ERROR(status);
 }
 
@@ -415,5 +586,5 @@
 
     status = pjsua_transport_close(id, PJ_FALSE);
-    PJSUA2_CHECK_RAISE_ERROR("Endpoint::transportClose()", status);
-}
-
+    PJSUA2_CHECK_RAISE_ERROR(status);
+}
+
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp	(revision 4600)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/types.cpp	(revision 4608)
@@ -18,4 +18,5 @@
  */
 #include <pjsua2/types.hpp>
+#include "util.hpp"
 
 using namespace pj;
@@ -23,30 +24,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-inline pj_str_t str2Pj(const string &is)
-{
-    pj_str_t os;
-    os.ptr = (char*)is.c_str();
-    os.slen = is.size();
-    return os;
-}
-
-inline string pj2Str(const pj_str_t &is)
-{
-    return string(is.ptr, is.slen);
-}
-
-///////////////////////////////////////////////////////////////////////////////
 
 Error::Error()
-: status(PJ_SUCCESS)
+: status(PJ_SUCCESS), srcLine(0)
 {
 }
 
 Error::Error( pj_status_t prm_status,
+	      const string &prm_title,
 	      const string &prm_reason,
-	      const string &prm_title,
 	      const string &prm_src_file,
 	      int prm_src_line)
-: status(prm_status), reason(prm_reason), title(prm_title),
+: status(prm_status), title(prm_title), reason(prm_reason),
   srcFile(prm_src_file), srcLine(prm_src_line)
 {
@@ -58,179 +45,4 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-
-AuthCredInfo::AuthCredInfo()
-: dataType(0)
-{
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-UaConfig::UaConfig()
-{
-    pjsua_config ua_cfg;
-
-    pjsua_config_default(&ua_cfg);
-    fromPj(ua_cfg);
-}
-
-void UaConfig::fromPj(const pjsua_config &ua_cfg)
-{
-    unsigned i;
-
-    this->maxCalls = ua_cfg.max_calls;
-    this->threadCnt = ua_cfg.thread_cnt;
-    this->userAgent = pj2Str(ua_cfg.user_agent);
-
-    for (i=0; i<ua_cfg.nameserver_count; ++i) {
-	this->nameserver.push_back(pj2Str(ua_cfg.nameserver[i]));
-    }
-
-    for (i=0; i<ua_cfg.stun_srv_cnt; ++i) {
-	this->stunServer.push_back(pj2Str(ua_cfg.stun_srv[i]));
-    }
-
-    this->stunIgnoreFailure = ua_cfg.stun_ignore_failure;
-    this->natTypeInSdp = ua_cfg.nat_type_in_sdp;
-    this->mwiUnsolicitedEnabled = ua_cfg.enable_unsolicited_mwi;
-}
-
-pjsua_config UaConfig::toPj() const
-{
-    unsigned i;
-    pjsua_config pua_cfg;
-
-    pjsua_config_default(&pua_cfg);
-
-    pua_cfg.max_calls = this->maxCalls;
-    pua_cfg.thread_cnt = this->threadCnt;
-    pua_cfg.user_agent = str2Pj(this->userAgent);
-
-    for (i=0; i<this->nameserver.size() && i<PJ_ARRAY_SIZE(pua_cfg.nameserver);
-	 ++i)
-    {
-	pua_cfg.nameserver[i] = str2Pj(this->nameserver[i]);
-    }
-    pua_cfg.nameserver_count = i;
-
-    for (i=0; i<this->stunServer.size() && i<PJ_ARRAY_SIZE(pua_cfg.stun_srv);
-	 ++i)
-    {
-	pua_cfg.stun_srv[i] = str2Pj(this->stunServer[i]);
-    }
-    pua_cfg.stun_srv_cnt = i;
-
-    pua_cfg.nat_type_in_sdp = this->natTypeInSdp;
-    pua_cfg.enable_unsolicited_mwi = this->mwiUnsolicitedEnabled;
-
-    return pua_cfg;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-LogConfig::LogConfig()
-{
-    pjsua_logging_config lc;
-
-    pjsua_logging_config_default(&lc);
-    fromPj(lc);
-}
-
-void LogConfig::fromPj(const pjsua_logging_config &lc)
-{
-    this->msgLogging = lc.msg_logging;
-    this->level = lc.level;
-    this->consoleLevel = lc.console_level;
-    this->decor = lc.decor;
-    this->filename = pj2Str(lc.log_filename);
-    this->fileFlags = lc.log_file_flags;
-    this->writer = NULL;
-}
-
-pjsua_logging_config LogConfig::toPj() const
-{
-    pjsua_logging_config lc;
-
-    pjsua_logging_config_default(&lc);
-
-    lc.msg_logging = this->msgLogging;
-    lc.level = this->level;
-    lc.console_level = this->consoleLevel;
-    lc.decor = this->decor;
-    lc.log_file_flags = this->fileFlags;
-    lc.log_filename = str2Pj(this->filename);
-
-    return lc;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MediaConfig::MediaConfig()
-{
-    pjsua_media_config mc;
-
-    pjsua_media_config_default(&mc);
-    fromPj(mc);
-}
-
-void MediaConfig::fromPj(const pjsua_media_config &mc)
-{
-    this->clockRate = mc.clock_rate;
-    this->sndClockRate = mc.snd_clock_rate;
-    this->channelCount = mc.channel_count;
-    this->audioFramePtime = mc.audio_frame_ptime;
-    this->maxMediaPorts = mc.max_media_ports;
-    this->hasIoqueue = mc.has_ioqueue;
-    this->threadCnt = mc.thread_cnt;
-    this->quality = mc.quality;
-    this->ptime = mc.ptime;
-    this->noVad = mc.no_vad;
-    this->ilbcMode = mc.ilbc_mode;
-    this->txDropPct = mc.tx_drop_pct;
-    this->rxDropPct = mc.rx_drop_pct;
-    this->ecOptions = mc.ec_options;
-    this->ecTailLen = mc.ec_tail_len;
-    this->sndRecLatency = mc.snd_rec_latency;
-    this->sndPlayLatency = mc.snd_play_latency;
-    this->jbInit = mc.jb_init;
-    this->jbMinPre = mc.jb_min_pre;
-    this->jbMaxPre = mc.jb_max_pre;
-    this->jbMax = mc.jb_max;
-    this->sndAutoCloseTime = mc.snd_auto_close_time;
-    this->vidPreviewEnableNative = mc.vid_preview_enable_native;
-}
-
-pjsua_media_config MediaConfig::toPj() const
-{
-    pjsua_media_config mcfg;
-
-    pjsua_media_config_default(&mcfg);
-
-    mcfg.clock_rate = this->clockRate;
-    mcfg.snd_clock_rate = this->sndClockRate;
-    mcfg.channel_count = this->channelCount;
-    mcfg.audio_frame_ptime = this->audioFramePtime;
-    mcfg.max_media_ports = this->maxMediaPorts;
-    mcfg.has_ioqueue = this->hasIoqueue;
-    mcfg.thread_cnt = this->threadCnt;
-    mcfg.quality = this->quality;
-    mcfg.ptime = this->ptime;
-    mcfg.no_vad = this->noVad;
-    mcfg.ilbc_mode = this->ilbcMode;
-    mcfg.tx_drop_pct = this->txDropPct;
-    mcfg.rx_drop_pct = this->rxDropPct;
-    mcfg.ec_options = this->ecOptions;
-    mcfg.ec_tail_len = this->ecTailLen;
-    mcfg.snd_rec_latency = this->sndRecLatency;
-    mcfg.snd_play_latency = this->sndPlayLatency;
-    mcfg.jb_init = this->jbInit;
-    mcfg.jb_min_pre = this->jbMinPre;
-    mcfg.jb_max_pre = this->jbMaxPre;
-    mcfg.jb_max = this->jbMax;
-    mcfg.snd_auto_close_time = this->sndAutoCloseTime;
-    mcfg.vid_preview_enable_native = this->vidPreviewEnableNative;
-
-    return mcfg;
-}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -299,4 +111,5 @@
 {
     this->port 		= prm.port;
+    this->portRange	= prm.port_range;
     this->publicAddress = pj2Str(prm.public_addr);
     this->boundAddress	= pj2Str(prm.bound_addr);
@@ -311,4 +124,5 @@
 
     tc.port		= this->port;
+    tc.port_range	= this->portRange;
     tc.public_addr	= str2Pj(this->publicAddress);
     tc.bound_addr	= str2Pj(this->boundAddress);
@@ -342,2 +156,37 @@
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+void SipHeader::fromPj(const pjsip_hdr *hdr) throw(Error)
+{
+    char buf[256];
+
+    int len = pjsip_hdr_print_on((void*)hdr, buf, sizeof(buf)-1);
+    if (len <= 0)
+	PJSUA2_RAISE_ERROR(PJ_ETOOSMALL);
+    buf[len] = '\0';
+
+    char *pos = strchr(buf, ':');
+    if (!pos)
+	PJSUA2_RAISE_ERROR(PJSIP_EINVALIDHDR);
+
+    // Trim white space after header name
+    char *end_name = pos;
+    while (end_name>buf && pj_isspace(*(end_name-1))) --end_name;
+
+    // Trim whitespaces after colon
+    char *start_val = pos+1;
+    while (*start_val && pj_isspace(*start_val)) ++start_val;
+
+    hName = string(buf, end_name);
+    hValue = string(start_val);
+}
+
+pjsip_generic_string_hdr &SipHeader::toPj() const
+{
+    pj_str_t hname  = str2Pj(hName);
+    pj_str_t hvalue = str2Pj(hValue);
+
+    pjsip_generic_string_hdr_init2(&pjHdr, &hname, &hvalue);
+    return pjHdr;
+}
Index: pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/util.hpp
===================================================================
--- pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/util.hpp	(revision 4608)
+++ pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/util.hpp	(revision 4608)
@@ -0,0 +1,41 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2012 Teluu Inc. (http://www.teluu.com)
+ *
+ * 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 <pjsua2/types.hpp>
+#include <string>
+
+namespace pj
+{
+using std::string;
+
+inline pj_str_t str2Pj(const string &input_str)
+{
+    pj_str_t output_str;
+    output_str.ptr = (char*)input_str.c_str();
+    output_str.slen = input_str.size();
+    return output_str;
+}
+
+inline string pj2Str(const pj_str_t &input_str)
+{
+    return string(input_str.ptr, input_str.slen);
+}
+
+
+}	// namespace
