* #36737: switch back to svn repo, remove assert in sip_transaction.c
diff --git a/jni/pjproject-android/.svn/pristine/25/2508212b8e773aaeedfe83aa9d5d8764b20ad520.svn-base b/jni/pjproject-android/.svn/pristine/25/2508212b8e773aaeedfe83aa9d5d8764b20ad520.svn-base
new file mode 100644
index 0000000..4f574f6
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/2508212b8e773aaeedfe83aa9d5d8764b20ad520.svn-base
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1536</int>
+ <string key="IBDocument.SystemVersion">12A206j</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2519</string>
+ <string key="IBDocument.AppKitVersion">1172.1</string>
+ <string key="IBDocument.HIToolboxVersion">613.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">1856</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>IBProxyObject</string>
+ <string>IBUIView</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="766721923">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 20}, {768, 1004}}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
+ <int key="IBUIStatusBarStyle">2</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="766721923"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="766721923"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.CustomClassName">ipjsuaViewController</string>
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="-2.CustomClassName">UIResponder</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">3</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">ipjsuaViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/ipjsuaViewController.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <bool key="IBDocument.UseAutolayout">YES</bool>
+ <string key="IBCocoaTouchPluginVersion">1856</string>
+ </data>
+</archive>
diff --git a/jni/pjproject-android/.svn/pristine/25/25388d2c4261eb57957410d6f5dbc729534b727f.svn-base b/jni/pjproject-android/.svn/pristine/25/25388d2c4261eb57957410d6f5dbc729534b727f.svn-base
new file mode 100644
index 0000000..9f37c32
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/25388d2c4261eb57957410d6f5dbc729534b727f.svn-base
@@ -0,0 +1,791 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_SIP_DIALOG_H__
+#define __PJSIP_SIP_DIALOG_H__
+
+
+/**
+ * @file sip_dialog.h
+ * @brief SIP Dialog abstraction
+ */
+
+#include <pjsip/sip_msg.h>
+#include <pjsip/sip_auth.h>
+#include <pjsip/sip_errno.h>
+#include <pjsip/sip_transport.h>
+#include <pjsip/sip_util.h>
+#include <pj/sock.h>
+#include <pj/assert.h>
+
+
+/**
+ * @defgroup PJSIP_DIALOG Base Dialog
+ * @ingroup PJSIP_UA
+ * @brief The base dialog framework to support dialog usages.
+ * @{
+ *
+ * The base dialog framework provides management for base dialog
+ * properties such as <b>From</b> header, <b>To</b> header, <b>CSeq</b>
+ * sequencing, <b>Call-ID</b> header, <b>Contact</b> header management,
+ * dialog <b>route-set</b> management, and common <b>authentication</b>.
+ * This basic dialog functionality will be shared by all <b>dialog
+ * usages</b> of a particular dialog.
+ *
+ * More detailed information is explained in
+ * <A HREF="/docs.htm">PJSIP Developer's Guide</A>
+ * PDF document, and readers are encouraged to read the document to
+ * get the concept behind dialog, dialog usages, and INVITE sessions.
+ *
+ * Application MUST initialize the user agent layer module by calling
+ * #pjsip_ua_init_module() before using any of the dialog API, and link
+ * the application with with <b>pjsip-core</b> library.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * This structure is used to describe dialog's participants, which in this
+ * case is local party (i.e. us) and remote party.
+ */
+typedef struct pjsip_dlg_party
+{
+ pjsip_fromto_hdr *info; /**< From/To header, inc tag. */
+ pj_str_t info_str; /**< String rep of info header. */
+ pj_uint32_t tag_hval; /**< Hashed value of the tag. */
+ pjsip_contact_hdr *contact; /**< Contact header. */
+ pj_int32_t first_cseq;/**< First CSeq seen. */
+ pj_int32_t cseq; /**< Next sequence number. */
+} pjsip_dlg_party;
+
+
+/**
+ * Dialog state.
+ */
+typedef enum pjsip_dialog_state
+{
+ /** Dialog is not established. */
+ PJSIP_DIALOG_STATE_NULL,
+
+ /** Dialog has been established (probably early) */
+ PJSIP_DIALOG_STATE_ESTABLISHED
+} pjsip_dialog_state;
+
+
+/**
+ * Dialog capability status.
+ */
+typedef enum pjsip_dialog_cap_status
+{
+ /** Capability is unsupported. */
+ PJSIP_DIALOG_CAP_UNSUPPORTED = 0,
+
+ /** Capability is supported */
+ PJSIP_DIALOG_CAP_SUPPORTED = 1,
+
+ /**
+ * Unknown capability status. This is usually because we lack the
+ * capability info which is retrieved from capability header specified
+ * in the dialog messages.
+ */
+ PJSIP_DIALOG_CAP_UNKNOWN = 2
+} pjsip_dialog_cap_status;
+
+
+/**
+ * This structure describes the dialog structure. Application MUST NOT
+ * try to SET the values here directly, but instead it MUST use the
+ * appropriate dialog API. The dialog declaration only needs to be made
+ * visible because other PJSIP modules need to see it (e.g. INVITE session,
+ * the event framework, etc.).
+ *
+ * Application MAY READ the dialog contents directly after it acquires
+ * dialog lock.
+ *
+ * To acquire dialog lock, use #pjsip_dlg_inc_lock(), and to release it,
+ * use #pjsip_dlg_dec_lock(). DO NOT USE pj_mutex_lock()/pj_mutex_unlock()
+ * on the dialog's mutex directly, because this will not protect against
+ * dialog being destroyed.
+ */
+struct pjsip_dialog
+{
+ /** The dialog set list. */
+ PJ_DECL_LIST_MEMBER(pjsip_dialog);
+
+ /* Dialog's system properties. */
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Standard id. */
+ pj_pool_t *pool; /**< Dialog's pool. */
+ pj_mutex_t *mutex_; /**< Dialog's mutex. Do not call!!
+ Use pjsip_dlg_inc_lock() instead! */
+ pjsip_user_agent *ua; /**< User agent instance. */
+ pjsip_endpoint *endpt; /**< Endpoint instance. */
+
+ /** The dialog set which this dialog belongs (opaque type). */
+ void *dlg_set;
+
+ /* Dialog's session properties. */
+ pjsip_dialog_state state; /**< Dialog state. */
+ pjsip_uri *target; /**< Current target. */
+ pjsip_target_set target_set; /**< Target set, for UAC only. */
+ pjsip_hdr inv_hdr; /**< Headers from hparam in dest URL */
+ pjsip_dlg_party local; /**< Local party info. */
+ pjsip_dlg_party remote; /**< Remote party info. */
+ pjsip_hdr rem_cap_hdr;/**< List of remote capability header. */
+ pjsip_role_e role; /**< Initial role. */
+ pj_bool_t uac_has_2xx;/**< UAC has received 2xx response? */
+ pj_bool_t secure; /**< Use secure transport? */
+ pj_bool_t add_allow; /**< Add Allow header in requests? */
+ pjsip_cid_hdr *call_id; /**< Call-ID header. */
+ pjsip_route_hdr route_set; /**< Route set. */
+ pj_bool_t route_set_frozen; /**< Route set has been set. */
+ pjsip_auth_clt_sess auth_sess; /**< Client authentication session. */
+
+ /** Session counter. */
+ int sess_count; /**< Number of sessions. */
+
+ /** Transaction counter. */
+ int tsx_count; /**< Number of pending transactions. */
+
+ /** Transport selector. */
+ pjsip_tpselector tp_sel;
+
+ /* Dialog usages. */
+ unsigned usage_cnt; /**< Number of registered usages. */
+ pjsip_module *usage[PJSIP_MAX_MODULE]; /**< Array of usages,
+ priority sorted */
+
+ /** Module specific data. */
+ void *mod_data[PJSIP_MAX_MODULE]; /**< Module data. */
+
+ /**
+ * If via_addr is set, it will be used as the "sent-by" field of the
+ * Via header for outgoing requests as long as the request uses via_tp
+ * transport. Normally application should not use or access these fields.
+ */
+ pjsip_host_port via_addr; /**< Via address. */
+ const void *via_tp; /**< Via transport. */
+};
+
+
+/**
+ * This utility function returns PJ_TRUE if the specified method is a
+ * dialog creating request. This method property is used to determine
+ * whether Contact header should be included in outgoing request.
+ *
+ * @param m The SIP method.
+ *
+ * @return PJ_TRUE if the method creates a dialog.
+ */
+PJ_DECL(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m);
+
+/**
+ * Create a new dialog and return the instance in p_dlg parameter.
+ * After creating the dialog, application can add modules as dialog usages
+ * by calling #pjsip_dlg_add_usage().
+ *
+ * If the request has To tag parameter, dialog's local tag will be initialized
+ * from this value. Otherwise a globally unique id generator will be invoked to
+ * create dialog's local tag.
+ *
+ * This function also initializes the dialog's route set based on the
+ * Record-Route headers in the request, if present.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param ua The user agent module instance.
+ * @param local_uri Dialog local URI (i.e. From header).
+ * @param local_contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the Contact will be taken
+ * from the local URI.
+ * @param remote_uri Dialog remote URI (i.e. To header).
+ * @param target Optional initial remote target. If this argument
+ * is NULL, the initial target will be set to
+ * remote URI.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
+ const pj_str_t *local_uri,
+ const pj_str_t *local_contact,
+ const pj_str_t *remote_uri,
+ const pj_str_t *target,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Initialize UAS dialog from the information found in the incoming request
+ * that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the
+ * local Contact to contact. If contact is not specified, the local contact
+ * is initialized from the URI in the To header in the request.
+ *
+ * This function will also create UAS transaction for the incoming request,
+ * and associate the transaction to the rdata. Application can query the
+ * transaction used to handle this request by calling #pjsip_rdata_get_tsx()
+ * after this function returns.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ *
+ * @param ua The user agent module instance.
+ * @param rdata The incoming request that creates the dialog,
+ * such as INVITE, SUBSCRIBE, or REFER.
+ * @param contact Optional dialog local Contact to be put as Contact
+ * header value, hence the format must follow
+ * RFC 3261 Section 20.10:
+ * When the header field value contains a display
+ * name, the URI including all URI parameters is
+ * enclosed in "<" and ">". If no "<" and ">" are
+ * present, all parameters after the URI are header
+ * parameters, not URI parameters. The display name
+ * can be tokens, or a quoted string, if a larger
+ * character set is desired.
+ * If this argument is NULL, the local contact will be
+ * initialized from the value of To header in the
+ * request.
+ * @param p_dlg Pointer to receive the dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
+ pjsip_rx_data *rdata,
+ const pj_str_t *contact,
+ pjsip_dialog **p_dlg);
+
+
+/**
+ * Lock/bind dialog to a specific transport/listener. This is optional,
+ * as normally transport will be selected automatically based on the
+ * destination of messages upon resolver completion. When the dialog is
+ * explicitly bound to the specific transport/listener, all transactions
+ * originated by this dialog will use the specified transport/listener
+ * when sending outgoing requests.
+ *
+ * Note that this doesn't affect the Contact header generated by this
+ * dialog. Application must manually update the Contact header if
+ * necessary, to adjust the address according to the transport being
+ * selected.
+ *
+ * @param dlg The dialog instance.
+ * @param sel Transport selector containing the specification of
+ * transport or listener to be used by this dialog
+ * to send requests.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg,
+ const pjsip_tpselector *sel);
+
+
+/**
+ * Set the "sent-by" field of the Via header for outgoing requests.
+ *
+ * @param dlg The dialog instance.
+ * @param via_addr Set via_addr to use for the Via header or NULL to use
+ * the transport's published name.
+ * @param via_tp via_addr will only be used if we are using via_tp
+ * transport.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_via_sent_by(pjsip_dialog *dlg,
+ pjsip_host_port *via_addr,
+ pjsip_transport *via_tp);
+
+
+/**
+ * Create a new (forked) dialog on receipt on forked response in rdata.
+ * The new dialog will be created from original_dlg, except that it will have
+ * new remote tag as copied from the To header in the response. Upon return,
+ * the new_dlg will have been registered to the user agent. Applications just
+ * need to add modules as dialog's usages.
+ *
+ * Note that initially, the session count in the dialog will be initialized
+ * to zero.
+ *
+ * @param original_dlg The original UAC dialog.
+ * @param rdata The incoming forked response message.
+ * @param new_dlg Pointer to receive the new dialog.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_fork(const pjsip_dialog *original_dlg,
+ const pjsip_rx_data *rdata,
+ pjsip_dialog **new_dlg );
+
+/**
+ * Forcefully terminate the dialog. Application can only call this function
+ * when there is no session associated to the dialog. If there are sessions
+ * that use this dialog, this function will refuse to terminate the dialog.
+ * For this case, application MUST call the appropriate termination function
+ * for each dialog session (e.g. #pjsip_inv_terminate() to terminate INVITE
+ * session).
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if dialog has been terminated.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg );
+
+
+/**
+ * Set dialog's initial route set to route_set list. This can only be called
+ * for UAC dialog, before any request is sent. After dialog has been
+ * established, the route set can not be changed.
+ *
+ * For UAS dialog,the route set will be initialized in pjsip_dlg_create_uas()
+ * from the Record-Route headers in the incoming request.
+ *
+ * The route_set argument is standard list of Route headers (i.e. with
+ * sentinel).
+ *
+ * @param dlg The UAC dialog.
+ * @param route_set List of Route header.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
+ const pjsip_route_hdr *route_set );
+
+/**
+ * Increment the number of sessions in the dialog. Note that initially
+ * (after created) the dialog has the session counter set to zero.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that increments the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+
+/**
+ * Decrement the number of sessions in the dialog. Once the session counter
+ * reach zero and there is no pending transaction, the dialog will be
+ * destroyed. Note that this function may destroy the dialog immediately
+ * if there is no pending transaction when this function is called.
+ *
+ * @param dlg The dialog.
+ * @param mod The module that decrements the session counter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
+ pjsip_module *mod);
+
+/**
+ * Add a module as dialog usage, and optionally set the module specific data.
+ *
+ * @param dlg The dialog.
+ * @param module The module to be registered as dialog usage.
+ * @param mod_data Optional arbitrary data to be attached to dialog's
+ * mod_data array at the module's index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
+ pjsip_module *module,
+ void *mod_data );
+
+/**
+ * Check if the specified module has been registered as usage to the dialog.
+ *
+ * @param dlg The dialog.
+ * @param module The module.
+ *
+ * @return PJ_TRUE if the specified module is currently
+ * registered as a usage to the dialog.
+ */
+PJ_DECL(pj_bool_t) pjsip_dlg_has_usage(pjsip_dialog *dlg,
+ pjsip_module *module);
+
+/**
+ * Attach module specific data to the dialog. Application can also set
+ * the value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * set to the dialog.
+ * @param data Arbitrary data.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
+ int mod_id,
+ void *data );
+
+/**
+ * Get module specific data previously attached to the dialog. Application
+ * can also get value directly by accessing dlg->mod_data[module_id].
+ *
+ * @param dlg The dialog
+ * @param mod_id The ID of the module from which the data is to be
+ * retrieved from the dialog.
+ *
+ * @return The data that was previously set, or NULL.
+ */
+PJ_DECL(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
+ int mod_id);
+
+
+/**
+ * Lock dialog and increment session counter termporarily, to prevent it
+ * from being destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Try to acquire dialog's lock, but return immediately if lock can not
+ * be acquired.
+ *
+ * @param dlg The dialog.
+ *
+ * @return PJ_SUCCESS if lock has been acquired.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_try_inc_lock( pjsip_dialog *dlg );
+
+/**
+ * Unlock dialog and decrement temporary session counter. After this function
+ * is called, dialog may be destroyed.
+ *
+ * @param dlg The dialog.
+ */
+PJ_DECL(void) pjsip_dlg_dec_lock( pjsip_dialog *dlg );
+
+
+/**
+ * Get the dialog instance in the incoming rdata. If an incoming message
+ * matches an existing dialog, the user agent must have put the matching
+ * dialog instance in the rdata, or otherwise this function will return
+ * NULL if the message didn't match any existing dialog.
+ *
+ * This function can only be called after endpoint distributes the message
+ * to the transaction layer or UA layer. In other words, application can
+ * only call this function in the context of module that runs in priority
+ * number higher than PJSIP_MOD_PRIORITY_UA_PROXY_LAYER.
+ *
+ * @param rdata Incoming message buffer.
+ *
+ * @return The dialog instance that "owns" the message.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata );
+
+/**
+ * Get the associated dialog for the specified transaction, if any.
+ *
+ * @param tsx The transaction.
+ *
+ * @return The dialog instance which has been registered
+ * to the transaction as transaction user, or
+ * NULL if the transaction is outside any dialogs.
+ */
+PJ_DECL(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx );
+
+
+/**
+ * Create a basic/generic request with the specified method and optionally
+ * specify the cseq. Use value -1 for cseq to have the dialog automatically
+ * put next cseq number for the request. Otherwise for some requests,
+ * e.q. CANCEL and ACK, application must put the CSeq in the original
+ * INVITE request as the parameter.
+ *
+ * This function will also put Contact header where appropriate.
+ *
+ * @param dlg The dialog instance.
+ * @param method The method of the request.
+ * @param cseq Optional CSeq, which only needs to be specified
+ * when creating ACK and CANCEL. For other requests,
+ * specify -1 to use dialog's internal counter.
+ * @param tdata Pointer to receive the request's transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
+ const pjsip_method *method,
+ int cseq,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Send request message to remote peer. If the request is not an ACK request,
+ * the dialog will send the request statefully, by creating an UAC transaction
+ * and send the request with the transaction.
+ *
+ * Also when the request is not ACK or CANCEL, the dialog will increment its
+ * local cseq number and update the cseq in the request according to dialog's
+ * cseq.
+ *
+ * If p_tsx is not null, this argument will be set with the transaction
+ * instance that was used to send the request.
+ *
+ * This function will decrement the transmit data's reference counter
+ * regardless the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tdata The request message to be sent.
+ * @param mod_data_id Optional module data index to put an optional data
+ * into the transaction. If no module data is to be
+ * attached, this value should be -1.
+ * @param mod_data Optional module data to be attached to the
+ * transaction at mod_data_id index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_request ( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int mod_data_id,
+ void *mod_data);
+
+
+/**
+ * Create a response message for the incoming request in rdata with status
+ * code st_code and optional status text st_text. This function is different
+ * than endpoint's API #pjsip_endpt_create_response() in that the dialog
+ * function adds Contact header and Record-Routes headers in the response
+ * where appropriate.
+ *
+ * @param dlg The dialog.
+ * @param rdata The incoming request message for which the
+ * response will be created.
+ * @param st_code Status code.
+ * @param st_text Optional string for custom status reason text.
+ * @param tdata Pointer to receive the response message transmit
+ * data buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_create_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ pjsip_tx_data **tdata);
+
+
+/**
+ * Modify previously sent response with other status code. Contact header
+ * will be added when appropriate.
+ *
+ * @param dlg The dialog.
+ * @param tdata The transmit data buffer containing response
+ * message to be modified.
+ * @param st_code New status code to be set.
+ * @param st_text Optional string for custom status reason text.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
+ pjsip_tx_data *tdata,
+ int st_code,
+ const pj_str_t *st_text);
+
+
+/**
+ * Send response message statefully. The transaction instance MUST be the
+ * transaction that was reported on on_rx_request() callback.
+ *
+ * This function decrements the transmit data's reference counter regardless
+ * the status of the operation.
+ *
+ * @param dlg The dialog.
+ * @param tsx The UAS transaction associated with the incoming
+ * request. If the request is within a dialog, or
+ * a dialog has been created for the request that
+ * creates the dialog, application can get the
+ * transaction instance for the request by calling
+ * #pjsip_rdata_get_tsx().
+ * @param tdata Response message to be sent.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_tx_data *tdata);
+
+
+/**
+ * This composite function sends response message statefully to an incoming
+ * request message inside dialog.
+ *
+ * @param dlg The endpoint instance.
+ * @param rdata The incoming request message.
+ * @param st_code Status code of the response.
+ * @param st_text Optional status text of the response.
+ * @param hdr_list Optional header list to be added to the response.
+ * @param body Optional message body to be added to the response.
+ *
+ * @return PJ_SUCCESS if response message has successfully been
+ * sent.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pj_str_t *st_text,
+ const pjsip_hdr *hdr_list,
+ const pjsip_msg_body *body );
+
+
+/**
+ * Check if remote peer have the specified capability as published
+ * in the dialog messages from remote peer.
+ *
+ * Notes:
+ * - The capability \a token lookup will apply exact match, but not
+ * case-sensitive, for example: <tt>"text/html"</tt> will not match
+ * <tt>"text / html"</tt> (notice the spaces).
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be checked, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ * @param token The capability token to check. For example, if \a htype
+ * is PJSIP_H_ALLOW, then \a token specifies the method
+ * names; if \a htype is PJSIP_H_SUPPORTED, then \a token
+ * specifies the extension names such as "100rel".
+ *
+ * @return PJSIP_DIALOG_CAP_SUPPORTED if the specified capability
+ * is explicitly supported, see @pjsip_dialog_cap_status
+ * for more info.
+ */
+PJ_DECL(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(
+ pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname,
+ const pj_str_t *token);
+
+/**
+ * Get the specified capability header from the remote capability headers
+ * stored in the dialog.
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be retrieved, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return The appropriate header, or NULL if the header is not
+ * available.
+ */
+PJ_DECL(const pjsip_hdr*) pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname);
+
+/**
+ * Set remote capability from a SIP header containing array of capability
+ * tags/values.
+ *
+ * @param dlg The dialog.
+ * @param cap_hdr The SIP header.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_set_remote_cap_hdr(
+ pjsip_dialog *dlg,
+ const pjsip_generic_array_hdr *cap_hdr);
+
+/**
+ * Remove a remote capability header.
+ *
+ * @param dlg The dialog.
+ * @param htype The header type to be removed, which value may be:
+ * - PJSIP_H_ACCEPT
+ * - PJSIP_H_ALLOW
+ * - PJSIP_H_SUPPORTED
+ * @param hname If htype specifies PJSIP_H_OTHER, then the header name
+ * must be supplied in this argument. Otherwise the value
+ * must be set to NULL.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg,
+ int htype,
+ const pj_str_t *hname);
+
+/**
+ * Update remote capabilities from a received message. The header types
+ * to be updated from the message will only be \a PJSIP_H_ACCEPT,
+ * \a PJSIP_H_ALLOW, and \a PJSIP_H_SUPPORTED.
+ *
+ * @param dlg The dialog.
+ * @param msg The received message.
+ * @param strict If this is set to PJ_TRUE, any header types missing
+ * from the message will cause removal of existing
+ * header types in the capability list. Otherwise, the
+ * capability list will not be modified when any header
+ * type is missing.
+ *
+ * @return PJ_SUCCESS when successful, otherwise the appropriate
+ * error code will be returned.
+ */
+PJ_DECL(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
+ const pjsip_msg *msg,
+ pj_bool_t strict);
+
+
+
+/**
+ * @}
+ */
+
+/*
+ * Internal (called by sip_ua_layer.c)
+ */
+
+/* Receives transaction event (called by user_agent module) */
+void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
+ pjsip_transaction *tsx,
+ pjsip_event *e );
+
+void pjsip_dlg_on_rx_request( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+void pjsip_dlg_on_rx_response( pjsip_dialog *dlg,
+ pjsip_rx_data *rdata );
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJSIP_SIP_DIALOG_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/25/255255a3266c1358c7f9c0508c2fb8c98ec2b1f9.svn-base b/jni/pjproject-android/.svn/pristine/25/255255a3266c1358c7f9c0508c2fb8c98ec2b1f9.svn-base
new file mode 100644
index 0000000..86c3d57
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/255255a3266c1358c7f9c0508c2fb8c98ec2b1f9.svn-base
@@ -0,0 +1,645 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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-codec/gsm.h>
+#include <pjmedia/codec.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/plc.h>
+#include <pjmedia/port.h>
+#include <pjmedia/silencedet.h>
+#include <pj/assert.h>
+#include <pj/pool.h>
+#include <pj/string.h>
+#include <pj/os.h>
+
+/*
+ * Only build this file if PJMEDIA_HAS_GSM_CODEC != 0
+ */
+#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC != 0
+
+#if defined(PJMEDIA_EXTERNAL_GSM_CODEC) && PJMEDIA_EXTERNAL_GSM_CODEC
+# if PJMEDIA_EXTERNAL_GSM_GSM_H
+# include <gsm/gsm.h>
+# elif PJMEDIA_EXTERNAL_GSM_H
+# include <gsm.h>
+# else
+# error Please set the location of gsm.h
+# endif
+#else
+# include "../../third_party/gsm/inc/gsm.h"
+#endif
+
+/* We removed PLC in 0.6 (and re-enabled it again in 0.9!) */
+#define PLC_DISABLED 0
+
+
+/* Prototypes for GSM factory */
+static pj_status_t gsm_test_alloc( pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *id );
+static pj_status_t gsm_default_attr( pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *id,
+ pjmedia_codec_param *attr );
+static pj_status_t gsm_enum_codecs( pjmedia_codec_factory *factory,
+ unsigned *count,
+ pjmedia_codec_info codecs[]);
+static pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *id,
+ pjmedia_codec **p_codec);
+static pj_status_t gsm_dealloc_codec( pjmedia_codec_factory *factory,
+ pjmedia_codec *codec );
+
+/* Prototypes for GSM implementation. */
+static pj_status_t gsm_codec_init( pjmedia_codec *codec,
+ pj_pool_t *pool );
+static pj_status_t gsm_codec_open( pjmedia_codec *codec,
+ pjmedia_codec_param *attr );
+static pj_status_t gsm_codec_close( pjmedia_codec *codec );
+static pj_status_t gsm_codec_modify(pjmedia_codec *codec,
+ const pjmedia_codec_param *attr );
+static pj_status_t gsm_codec_parse( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *ts,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[]);
+static pj_status_t gsm_codec_encode( pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output);
+static pj_status_t gsm_codec_decode( pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output);
+#if !PLC_DISABLED
+static pj_status_t gsm_codec_recover(pjmedia_codec *codec,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output);
+#endif
+
+/* Definition for GSM codec operations. */
+static pjmedia_codec_op gsm_op =
+{
+ &gsm_codec_init,
+ &gsm_codec_open,
+ &gsm_codec_close,
+ &gsm_codec_modify,
+ &gsm_codec_parse,
+ &gsm_codec_encode,
+ &gsm_codec_decode,
+#if !PLC_DISABLED
+ &gsm_codec_recover
+#else
+ NULL
+#endif
+};
+
+/* Definition for GSM codec factory operations. */
+static pjmedia_codec_factory_op gsm_factory_op =
+{
+ &gsm_test_alloc,
+ &gsm_default_attr,
+ &gsm_enum_codecs,
+ &gsm_alloc_codec,
+ &gsm_dealloc_codec,
+ &pjmedia_codec_gsm_deinit
+};
+
+/* GSM factory */
+static struct gsm_codec_factory
+{
+ pjmedia_codec_factory base;
+ pjmedia_endpt *endpt;
+ pj_pool_t *pool;
+ pj_mutex_t *mutex;
+ pjmedia_codec codec_list;
+} gsm_codec_factory;
+
+
+/* GSM codec private data. */
+struct gsm_data
+{
+ struct gsm_state *encoder;
+ struct gsm_state *decoder;
+ pj_bool_t plc_enabled;
+#if !PLC_DISABLED
+ pjmedia_plc *plc;
+#endif
+ pj_bool_t vad_enabled;
+ pjmedia_silence_det *vad;
+ pj_timestamp last_tx;
+};
+
+
+
+/*
+ * Initialize and register GSM codec factory to pjmedia endpoint.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_gsm_init( pjmedia_endpt *endpt )
+{
+ pjmedia_codec_mgr *codec_mgr;
+ pj_status_t status;
+
+ if (gsm_codec_factory.pool != NULL)
+ return PJ_SUCCESS;
+
+ /* Create GSM codec factory. */
+ gsm_codec_factory.base.op = &gsm_factory_op;
+ gsm_codec_factory.base.factory_data = NULL;
+ gsm_codec_factory.endpt = endpt;
+
+ gsm_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "gsm", 4000,
+ 4000);
+ if (!gsm_codec_factory.pool)
+ return PJ_ENOMEM;
+
+ pj_list_init(&gsm_codec_factory.codec_list);
+
+ /* Create mutex. */
+ status = pj_mutex_create_simple(gsm_codec_factory.pool, "gsm",
+ &gsm_codec_factory.mutex);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Get the codec manager. */
+ codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
+ if (!codec_mgr) {
+ status = PJ_EINVALIDOP;
+ goto on_error;
+ }
+
+ /* Register codec factory to endpoint. */
+ status = pjmedia_codec_mgr_register_factory(codec_mgr,
+ &gsm_codec_factory.base);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Done. */
+ return PJ_SUCCESS;
+
+on_error:
+ pj_pool_release(gsm_codec_factory.pool);
+ gsm_codec_factory.pool = NULL;
+ return status;
+}
+
+
+
+/*
+ * Unregister GSM codec factory from pjmedia endpoint and deinitialize
+ * the GSM codec library.
+ */
+PJ_DEF(pj_status_t) pjmedia_codec_gsm_deinit(void)
+{
+ pjmedia_codec_mgr *codec_mgr;
+ pj_status_t status;
+
+ if (gsm_codec_factory.pool == NULL)
+ return PJ_SUCCESS;
+
+ /* We don't want to deinit if there's outstanding codec. */
+ /* This is silly, as we'll always have codec in the list if
+ we ever allocate a codec! A better behavior maybe is to
+ deallocate all codecs in the list.
+ pj_mutex_lock(gsm_codec_factory.mutex);
+ if (!pj_list_empty(&gsm_codec_factory.codec_list)) {
+ pj_mutex_unlock(gsm_codec_factory.mutex);
+ return PJ_EBUSY;
+ }
+ */
+
+ /* Get the codec manager. */
+ codec_mgr = pjmedia_endpt_get_codec_mgr(gsm_codec_factory.endpt);
+ if (!codec_mgr) {
+ pj_pool_release(gsm_codec_factory.pool);
+ gsm_codec_factory.pool = NULL;
+ return PJ_EINVALIDOP;
+ }
+
+ /* Unregister GSM codec factory. */
+ status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
+ &gsm_codec_factory.base);
+
+ /* Destroy mutex. */
+ pj_mutex_destroy(gsm_codec_factory.mutex);
+
+ /* Destroy pool. */
+ pj_pool_release(gsm_codec_factory.pool);
+ gsm_codec_factory.pool = NULL;
+
+ return status;
+}
+
+/*
+ * Check if factory can allocate the specified codec.
+ */
+static pj_status_t gsm_test_alloc( pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info )
+{
+ PJ_UNUSED_ARG(factory);
+
+ /* Check payload type. */
+ if (info->pt != PJMEDIA_RTP_PT_GSM)
+ return PJMEDIA_CODEC_EUNSUP;
+
+ /* Ignore the rest, since it's static payload type. */
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Generate default attribute.
+ */
+static pj_status_t gsm_default_attr (pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *id,
+ pjmedia_codec_param *attr )
+{
+ PJ_UNUSED_ARG(factory);
+ PJ_UNUSED_ARG(id);
+
+ pj_bzero(attr, sizeof(pjmedia_codec_param));
+ attr->info.clock_rate = 8000;
+ attr->info.channel_cnt = 1;
+ attr->info.avg_bps = 13200;
+ attr->info.max_bps = 13200;
+ attr->info.pcm_bits_per_sample = 16;
+ attr->info.frm_ptime = 20;
+ attr->info.pt = PJMEDIA_RTP_PT_GSM;
+
+ attr->setting.frm_per_pkt = 1;
+ attr->setting.vad = 1;
+#if !PLC_DISABLED
+ attr->setting.plc = 1;
+#endif
+
+ /* Default all other flag bits disabled. */
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Enum codecs supported by this factory (i.e. only GSM!).
+ */
+static pj_status_t gsm_enum_codecs(pjmedia_codec_factory *factory,
+ unsigned *count,
+ pjmedia_codec_info codecs[])
+{
+ PJ_UNUSED_ARG(factory);
+ PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
+
+ pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));
+ codecs[0].encoding_name = pj_str("GSM");
+ codecs[0].pt = PJMEDIA_RTP_PT_GSM;
+ codecs[0].type = PJMEDIA_TYPE_AUDIO;
+ codecs[0].clock_rate = 8000;
+ codecs[0].channel_cnt = 1;
+
+ *count = 1;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Allocate a new GSM codec instance.
+ */
+static pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *id,
+ pjmedia_codec **p_codec)
+{
+ pjmedia_codec *codec;
+ struct gsm_data *gsm_data;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
+ PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL);
+
+
+ pj_mutex_lock(gsm_codec_factory.mutex);
+
+ /* Get free nodes, if any. */
+ if (!pj_list_empty(&gsm_codec_factory.codec_list)) {
+ codec = gsm_codec_factory.codec_list.next;
+ pj_list_erase(codec);
+ } else {
+ codec = PJ_POOL_ZALLOC_T(gsm_codec_factory.pool, pjmedia_codec);
+ PJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);
+ codec->op = &gsm_op;
+ codec->factory = factory;
+
+ gsm_data = PJ_POOL_ZALLOC_T(gsm_codec_factory.pool, struct gsm_data);
+ codec->codec_data = gsm_data;
+
+#if !PLC_DISABLED
+ /* Create PLC */
+ status = pjmedia_plc_create(gsm_codec_factory.pool, 8000,
+ 160, 0, &gsm_data->plc);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(gsm_codec_factory.mutex);
+ return status;
+ }
+#endif
+
+ /* Create silence detector */
+ status = pjmedia_silence_det_create(gsm_codec_factory.pool,
+ 8000, 160,
+ &gsm_data->vad);
+ if (status != PJ_SUCCESS) {
+ pj_mutex_unlock(gsm_codec_factory.mutex);
+ return status;
+ }
+ }
+
+ pj_mutex_unlock(gsm_codec_factory.mutex);
+
+ *p_codec = codec;
+ return PJ_SUCCESS;
+}
+
+/*
+ * Free codec.
+ */
+static pj_status_t gsm_dealloc_codec( pjmedia_codec_factory *factory,
+ pjmedia_codec *codec )
+{
+ struct gsm_data *gsm_data;
+ int i;
+
+ PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
+ PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL);
+
+ gsm_data = (struct gsm_data*) codec->codec_data;
+
+ /* Close codec, if it's not closed. */
+ gsm_codec_close(codec);
+
+#if !PLC_DISABLED
+ /* Clear left samples in the PLC, since codec+plc will be reused
+ * next time.
+ */
+ for (i=0; i<2; ++i) {
+ pj_int16_t frame[160];
+ pjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame));
+ pjmedia_plc_save(gsm_data->plc, frame);
+ }
+#else
+ PJ_UNUSED_ARG(i);
+#endif
+
+ /* Re-init silence_period */
+ pj_set_timestamp32(&gsm_data->last_tx, 0, 0);
+
+ /* Put in the free list. */
+ pj_mutex_lock(gsm_codec_factory.mutex);
+ pj_list_push_front(&gsm_codec_factory.codec_list, codec);
+ pj_mutex_unlock(gsm_codec_factory.mutex);
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Init codec.
+ */
+static pj_status_t gsm_codec_init( pjmedia_codec *codec,
+ pj_pool_t *pool )
+{
+ PJ_UNUSED_ARG(codec);
+ PJ_UNUSED_ARG(pool);
+ return PJ_SUCCESS;
+}
+
+/*
+ * Open codec.
+ */
+static pj_status_t gsm_codec_open( pjmedia_codec *codec,
+ pjmedia_codec_param *attr )
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+
+ pj_assert(gsm_data != NULL);
+ pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL);
+
+ gsm_data->encoder = gsm_create();
+ if (!gsm_data->encoder)
+ return PJMEDIA_CODEC_EFAILED;
+
+ gsm_data->decoder = gsm_create();
+ if (!gsm_data->decoder)
+ return PJMEDIA_CODEC_EFAILED;
+
+ gsm_data->vad_enabled = (attr->setting.vad != 0);
+ gsm_data->plc_enabled = (attr->setting.plc != 0);
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Close codec.
+ */
+static pj_status_t gsm_codec_close( pjmedia_codec *codec )
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+
+ pj_assert(gsm_data != NULL);
+
+ if (gsm_data->encoder) {
+ gsm_destroy(gsm_data->encoder);
+ gsm_data->encoder = NULL;
+ }
+ if (gsm_data->decoder) {
+ gsm_destroy(gsm_data->decoder);
+ gsm_data->decoder = NULL;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t gsm_codec_modify(pjmedia_codec *codec,
+ const pjmedia_codec_param *attr )
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+
+ pj_assert(gsm_data != NULL);
+ pj_assert(gsm_data->encoder != NULL && gsm_data->decoder != NULL);
+
+ gsm_data->vad_enabled = (attr->setting.vad != 0);
+ gsm_data->plc_enabled = (attr->setting.plc != 0);
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get frames in the packet.
+ */
+static pj_status_t gsm_codec_parse( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *ts,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[])
+{
+ unsigned count = 0;
+
+ PJ_UNUSED_ARG(codec);
+
+ PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
+
+ while (pkt_size >= 33 && count < *frame_cnt) {
+ frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
+ frames[count].buf = pkt;
+ frames[count].size = 33;
+ frames[count].timestamp.u64 = ts->u64 + count * 160;
+
+ pkt = ((char*)pkt) + 33;
+ pkt_size -= 33;
+
+ ++count;
+ }
+
+ *frame_cnt = count;
+ return PJ_SUCCESS;
+}
+
+/*
+ * Encode frame.
+ */
+static pj_status_t gsm_codec_encode( pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output)
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+ pj_int16_t *pcm_in;
+ pj_size_t in_size;
+
+ pj_assert(gsm_data && input && output);
+
+ pcm_in = (pj_int16_t*)input->buf;
+ in_size = input->size;
+
+ PJ_ASSERT_RETURN(in_size % 320 == 0, PJMEDIA_CODEC_EPCMFRMINLEN);
+ PJ_ASSERT_RETURN(output_buf_len >= 33 * in_size/320,
+ PJMEDIA_CODEC_EFRMTOOSHORT);
+
+ /* Detect silence */
+ if (gsm_data->vad_enabled) {
+ pj_bool_t is_silence;
+ pj_int32_t silence_duration;
+
+ silence_duration = pj_timestamp_diff32(&gsm_data->last_tx,
+ &input->timestamp);
+
+ is_silence = pjmedia_silence_det_detect(gsm_data->vad,
+ (const pj_int16_t*) input->buf,
+ (input->size >> 1),
+ NULL);
+ if (is_silence &&
+ (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
+ silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
+ {
+ output->type = PJMEDIA_FRAME_TYPE_NONE;
+ output->buf = NULL;
+ output->size = 0;
+ output->timestamp = input->timestamp;
+ return PJ_SUCCESS;
+ } else {
+ gsm_data->last_tx = input->timestamp;
+ }
+ }
+
+ /* Encode */
+ output->size = 0;
+ while (in_size >= 320) {
+ gsm_encode(gsm_data->encoder, pcm_in,
+ (unsigned char*)output->buf + output->size);
+ pcm_in += 160;
+ output->size += 33;
+ in_size -= 320;
+ }
+
+ output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ output->timestamp = input->timestamp;
+
+ return PJ_SUCCESS;
+}
+
+/*
+ * Decode frame.
+ */
+static pj_status_t gsm_codec_decode( pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output)
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+
+ pj_assert(gsm_data != NULL);
+ PJ_ASSERT_RETURN(input && output, PJ_EINVAL);
+
+ if (output_buf_len < 320)
+ return PJMEDIA_CODEC_EPCMTOOSHORT;
+
+ if (input->size < 33)
+ return PJMEDIA_CODEC_EFRMTOOSHORT;
+
+ gsm_decode(gsm_data->decoder,
+ (unsigned char*)input->buf,
+ (short*)output->buf);
+
+ output->size = 320;
+ output->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ output->timestamp = input->timestamp;
+
+#if !PLC_DISABLED
+ if (gsm_data->plc_enabled)
+ pjmedia_plc_save( gsm_data->plc, (pj_int16_t*)output->buf);
+#endif
+
+ return PJ_SUCCESS;
+}
+
+
+#if !PLC_DISABLED
+/*
+ * Recover lost frame.
+ */
+static pj_status_t gsm_codec_recover(pjmedia_codec *codec,
+ unsigned output_buf_len,
+ struct pjmedia_frame *output)
+{
+ struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
+
+ PJ_ASSERT_RETURN(gsm_data->plc_enabled, PJ_EINVALIDOP);
+
+ PJ_ASSERT_RETURN(output_buf_len >= 320, PJMEDIA_CODEC_EPCMTOOSHORT);
+
+ pjmedia_plc_generate(gsm_data->plc, (pj_int16_t*)output->buf);
+ output->size = 320;
+
+ return PJ_SUCCESS;
+}
+#endif
+
+
+#endif /* PJMEDIA_HAS_GSM_CODEC */
+
diff --git a/jni/pjproject-android/.svn/pristine/25/2560f472573d73e0a272ecc68a60e306e3ff3f77.svn-base b/jni/pjproject-android/.svn/pristine/25/2560f472573d73e0a272ecc68a60e306e3ff3f77.svn-base
new file mode 100644
index 0000000..2fa6334
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/2560f472573d73e0a272ecc68a60e306e3ff3f77.svn-base
@@ -0,0 +1,822 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 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 <pjmedia-videodev/videodev_imp.h>
+#include <pjmedia/errno.h>
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/file_access.h>
+#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/rand.h>
+
+#if PJMEDIA_VIDEO_DEV_HAS_V4L2
+
+#include <linux/videodev2.h>
+#include <libv4l2.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#define THIS_FILE "v4l2_dev.c"
+#define DRIVER_NAME "v4l2"
+#define V4L2_MAX_DEVS 4
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_FPS 25
+#define DEFAULT_CLOCK_RATE 90000
+#define INVALID_FD -1
+#define BUFFER_CNT 2
+#define MAX_IOCTL_RETRY 20
+
+
+/* mapping between pjmedia_fmt_id and v4l2 pixel format */
+typedef struct vid4lin_fmt_map
+{
+ pj_uint32_t pjmedia_fmt_id;
+ pj_uint32_t v4l2_fmt_id;
+} vid4lin_fmt_map;
+
+/* I/O type being used */
+enum vid4lin_io_type
+{
+ IO_TYPE_NONE,
+ IO_TYPE_READ,
+ IO_TYPE_MMAP,
+ IO_TYPE_MMAP_USER
+};
+
+/* descriptor for each mmap-ed buffer */
+typedef struct vid4lin_buffer
+{
+ void *start;
+ size_t length;
+} vid4lin_buffer;
+
+/* v4l2 device info */
+typedef struct vid4lin_dev_info
+{
+ pjmedia_vid_dev_info info;
+ char dev_name[32];
+ struct v4l2_capability v4l2_cap;
+} vid4lin_dev_info;
+
+/* v4l2 factory */
+typedef struct vid4lin_factory
+{
+ pjmedia_vid_dev_factory base;
+ pj_pool_t *pool;
+ pj_pool_t *dev_pool;
+ pj_pool_factory *pf;
+
+ unsigned dev_count;
+ vid4lin_dev_info *dev_info;
+} vid4lin_factory;
+
+/* Video stream. */
+typedef struct vid4lin_stream
+{
+ pjmedia_vid_dev_stream base; /**< Base stream */
+ pjmedia_vid_dev_param param; /**< Settings */
+ pj_pool_t *pool; /**< Memory pool. */
+
+ int fd; /**< Video fd. */
+ char name[64]; /**< Name for log */
+ enum vid4lin_io_type io_type; /**< I/O method. */
+ unsigned buf_cnt; /**< MMap buf cnt. */
+ vid4lin_buffer *buffers; /**< MMap buffers. */
+ pj_time_val start_time; /**< Time when started */
+
+ pjmedia_vid_dev_cb vid_cb; /**< Stream callback */
+ void *user_data; /**< Application data */
+} vid4lin_stream;
+
+/* Use this to convert between pjmedia_format_id and V4L2 fourcc */
+static vid4lin_fmt_map v4l2_fmt_maps[] =
+{
+ { PJMEDIA_FORMAT_RGB24, V4L2_PIX_FMT_BGR24 },
+ { PJMEDIA_FORMAT_RGBA, V4L2_PIX_FMT_BGR32 },
+ { PJMEDIA_FORMAT_RGB32, V4L2_PIX_FMT_BGR32 },
+ { PJMEDIA_FORMAT_AYUV, V4L2_PIX_FMT_YUV32 },
+ { PJMEDIA_FORMAT_YUY2, V4L2_PIX_FMT_YUYV },
+ { PJMEDIA_FORMAT_UYVY, V4L2_PIX_FMT_UYVY }
+};
+
+/* Prototypes */
+static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f);
+static unsigned vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f);
+static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+static pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+static pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *prm,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p);
+
+static pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+static pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+static pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+static pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+static pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm);
+static pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm);
+static pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm);
+
+/* Operations */
+static pjmedia_vid_dev_factory_op factory_op =
+{
+ &vid4lin_factory_init,
+ &vid4lin_factory_destroy,
+ &vid4lin_factory_get_dev_count,
+ &vid4lin_factory_get_dev_info,
+ &vid4lin_factory_default_param,
+ &vid4lin_factory_create_stream,
+ &vid4lin_factory_refresh
+};
+
+static pjmedia_vid_dev_stream_op stream_op =
+{
+ &vid4lin_stream_get_param,
+ &vid4lin_stream_get_cap,
+ &vid4lin_stream_set_cap,
+ &vid4lin_stream_start,
+ &vid4lin_stream_get_frame,
+ NULL,
+ &vid4lin_stream_stop,
+ &vid4lin_stream_destroy
+};
+
+
+/****************************************************************************
+ * Factory operations
+ */
+/*
+ * Factory creation function.
+ */
+pjmedia_vid_dev_factory* pjmedia_v4l2_factory(pj_pool_factory *pf)
+{
+ vid4lin_factory *f;
+ pj_pool_t *pool;
+
+ pool = pj_pool_create(pf, DRIVER_NAME, 512, 512, NULL);
+ f = PJ_POOL_ZALLOC_T(pool, vid4lin_factory);
+ f->pf = pf;
+ f->pool = pool;
+ f->base.op = &factory_op;
+
+ return &f->base;
+}
+
+/* util: ioctl that tries harder. */
+static pj_status_t xioctl(int fh, int request, void *arg)
+{
+ enum { RETRY = MAX_IOCTL_RETRY };
+ int r, c=0;
+
+ do {
+ r = v4l2_ioctl(fh, request, arg);
+ } while (r==-1 && c++<RETRY && ((errno==EINTR) || (errno==EAGAIN)));
+
+ return (r == -1) ? pj_get_os_error() : PJ_SUCCESS;
+}
+
+/* Scan V4L2 devices */
+static pj_status_t v4l2_scan_devs(vid4lin_factory *f)
+{
+ vid4lin_dev_info vdi[V4L2_MAX_DEVS];
+ char dev_name[32];
+ unsigned i, old_count;
+ pj_status_t status;
+
+ if (f->dev_pool) {
+ pj_pool_release(f->dev_pool);
+ f->dev_pool = NULL;
+ }
+
+ pj_bzero(vdi, sizeof(vdi));
+ old_count = f->dev_count;
+ f->dev_count = 0;
+ f->dev_pool = pj_pool_create(f->pf, DRIVER_NAME, 500, 500, NULL);
+
+ for (i=0; i<V4L2_MAX_DEVS && f->dev_count < V4L2_MAX_DEVS; ++i) {
+ int fd;
+ vid4lin_dev_info *pdi;
+ pj_uint32_t fmt_cap[8];
+ int j, fmt_cnt=0;
+
+ pdi = &vdi[f->dev_count];
+
+ snprintf(dev_name, sizeof(dev_name), "/dev/video%d", i);
+ if (!pj_file_exists(dev_name))
+ continue;
+
+ fd = v4l2_open(dev_name, O_RDWR, 0);
+ if (fd == -1)
+ continue;
+
+ status = xioctl(fd, VIDIOC_QUERYCAP, &pdi->v4l2_cap);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4,(THIS_FILE, status, "Error querying %s", dev_name));
+ v4l2_close(fd);
+ continue;
+ }
+
+ if ((pdi->v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
+ v4l2_close(fd);
+ continue;
+ }
+
+ PJ_LOG(5,(THIS_FILE, "Found capture device %s", pdi->v4l2_cap.card));
+ PJ_LOG(5,(THIS_FILE, " Enumerating formats:"));
+ for (j=0; fmt_cnt<PJ_ARRAY_SIZE(fmt_cap); ++j) {
+ struct v4l2_fmtdesc fdesc;
+ unsigned k;
+
+ pj_bzero(&fdesc, sizeof(fdesc));
+ fdesc.index = j;
+ fdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ status = xioctl(fd, VIDIOC_ENUM_FMT, &fdesc);
+ if (status != PJ_SUCCESS)
+ break;
+
+ for (k=0; k<PJ_ARRAY_SIZE(v4l2_fmt_maps); ++k) {
+ if (v4l2_fmt_maps[k].v4l2_fmt_id == fdesc.pixelformat) {
+ fmt_cap[fmt_cnt++] = v4l2_fmt_maps[k].pjmedia_fmt_id;
+ PJ_LOG(5,(THIS_FILE, " Supported: %s",
+ fdesc.description));
+ break;
+ }
+ }
+ if (k==PJ_ARRAY_SIZE(v4l2_fmt_maps)) {
+ PJ_LOG(5,(THIS_FILE, " Unsupported: %s", fdesc.description));
+ }
+ }
+
+ v4l2_close(fd);
+
+ if (fmt_cnt==0) {
+ PJ_LOG(5,(THIS_FILE, " Found no common format"));
+ continue;
+ }
+
+ strncpy(pdi->dev_name, dev_name, sizeof(pdi->dev_name));
+ pdi->dev_name[sizeof(pdi->dev_name)-1] = '\0';
+ strncpy(pdi->info.name, (char*)pdi->v4l2_cap.card,
+ sizeof(pdi->info.name));
+ pdi->info.name[sizeof(pdi->info.name)-1] = '\0';
+ strncpy(pdi->info.driver, DRIVER_NAME, sizeof(pdi->info.driver));
+ pdi->info.driver[sizeof(pdi->info.driver)-1] = '\0';
+ pdi->info.dir = PJMEDIA_DIR_CAPTURE;
+ pdi->info.has_callback = PJ_FALSE;
+ pdi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
+
+ pdi->info.fmt_cnt = fmt_cnt;
+ for (j=0; j<fmt_cnt; ++j) {
+ pjmedia_format_init_video(&pdi->info.fmt[j],
+ fmt_cap[j],
+ DEFAULT_WIDTH,
+ DEFAULT_HEIGHT,
+ DEFAULT_FPS, 1);
+ }
+ if (j < fmt_cnt)
+ continue;
+
+ f->dev_count++;
+ }
+
+ if (f->dev_count == 0)
+ return PJ_SUCCESS;
+
+ if (f->dev_count > old_count || f->dev_info == NULL) {
+ f->dev_info = (vid4lin_dev_info*)
+ pj_pool_calloc(f->dev_pool,
+ f->dev_count,
+ sizeof(vid4lin_dev_info));
+ }
+ pj_memcpy(f->dev_info, vdi, f->dev_count * sizeof(vid4lin_dev_info));
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: init factory */
+static pj_status_t vid4lin_factory_init(pjmedia_vid_dev_factory *f)
+{
+ return vid4lin_factory_refresh(f);
+}
+
+/* API: destroy factory */
+static pj_status_t vid4lin_factory_destroy(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_pool_t *pool = cf->pool;
+
+ if (cf->dev_pool)
+ pj_pool_release(cf->dev_pool);
+ if (cf->pool) {
+ cf->pool = NULL;
+ pj_pool_release(pool);
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the list of devices */
+static pj_status_t vid4lin_factory_refresh(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_status_t status;
+
+ status = v4l2_scan_devs(cf);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ PJ_LOG(4, (THIS_FILE, "Video4Linux2 has %d devices",
+ cf->dev_count));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get number of devices */
+static unsigned vid4lin_factory_get_dev_count(pjmedia_vid_dev_factory *f)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ return cf->dev_count;
+}
+
+/* API: get device info */
+static pj_status_t vid4lin_factory_get_dev_info(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_memcpy(info, &cf->dev_info[index].info, sizeof(*info));
+
+ return PJ_SUCCESS;
+}
+
+/* API: create default device parameter */
+static pj_status_t vid4lin_factory_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+
+ PJ_ASSERT_RETURN(index < cf->dev_count, PJMEDIA_EVID_INVDEV);
+
+ pj_bzero(param, sizeof(*param));
+ param->dir = PJMEDIA_DIR_CAPTURE;
+ param->cap_id = index;
+ param->rend_id = PJMEDIA_VID_INVALID_DEV;
+ param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
+ param->clock_rate = DEFAULT_CLOCK_RATE;
+ pjmedia_format_copy(¶m->fmt, &cf->dev_info[index].info.fmt[0]);
+
+ return PJ_SUCCESS;
+}
+
+static vid4lin_fmt_map* get_v4l2_format_info(pjmedia_format_id id)
+{
+ unsigned i;
+
+ for (i = 0; i < PJ_ARRAY_SIZE(v4l2_fmt_maps); i++) {
+ if (v4l2_fmt_maps[i].pjmedia_fmt_id == id)
+ return &v4l2_fmt_maps[i];
+ }
+
+ return NULL;
+}
+
+/* util: setup format */
+static pj_status_t vid4lin_stream_init_fmt(vid4lin_stream *stream,
+ const pjmedia_vid_dev_param *param,
+ pj_uint32_t pix_fmt)
+{
+ pjmedia_video_format_detail *vfd;
+ struct v4l2_format v4l2_fmt;
+ pj_status_t status;
+
+ vfd = pjmedia_format_get_video_format_detail(¶m->fmt, PJ_TRUE);
+ if (vfd == NULL)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ pj_bzero(&v4l2_fmt, sizeof(v4l2_fmt));
+ v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ v4l2_fmt.fmt.pix.width = vfd->size.w;
+ v4l2_fmt.fmt.pix.height = vfd->size.h;
+ v4l2_fmt.fmt.pix.pixelformat = pix_fmt;
+ v4l2_fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+ status = xioctl(stream->fd, VIDIOC_S_FMT, &v4l2_fmt);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (v4l2_fmt.fmt.pix.pixelformat != pix_fmt) {
+ status = PJMEDIA_EVID_BADFORMAT;
+ return status;
+ }
+
+ if ((v4l2_fmt.fmt.pix.width != vfd->size.w) ||
+ (v4l2_fmt.fmt.pix.height != vfd->size.h))
+ {
+ /* Size has changed */
+ vfd->size.w = v4l2_fmt.fmt.pix.width;
+ vfd->size.h = v4l2_fmt.fmt.pix.height;
+ }
+
+ return PJ_SUCCESS;
+}
+
+/* Util: initiate v4l2 streaming via mmap */
+static pj_status_t vid4lin_stream_init_streaming(vid4lin_stream *stream)
+{
+ struct v4l2_requestbuffers req;
+ unsigned i;
+ pj_status_t status;
+
+ pj_bzero(&req, sizeof(req));
+ req.count = BUFFER_CNT;
+ req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req.memory = V4L2_MEMORY_MMAP;
+ status = xioctl(stream->fd, VIDIOC_REQBUFS, &req);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ stream->buffers = pj_pool_calloc(stream->pool, req.count,
+ sizeof(*stream->buffers));
+ stream->buf_cnt = 0;
+
+ for (i = 0; i < req.count; ++i) {
+ struct v4l2_buffer buf;
+
+ pj_bzero(&buf, sizeof(buf));
+
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+
+ status = xioctl(stream->fd, VIDIOC_QUERYBUF, &buf);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ stream->buffers[i].length = buf.length;
+ stream->buffers[i].start = v4l2_mmap(NULL, buf.length,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, stream->fd,
+ buf.m.offset);
+
+ if (MAP_FAILED == stream->buffers[i].start) {
+ status = pj_get_os_error();
+ goto on_error;
+ }
+
+ stream->buf_cnt++;
+ }
+
+ PJ_LOG(5,(THIS_FILE, " mmap streaming initialized"));
+
+ stream->io_type = IO_TYPE_MMAP;
+ return PJ_SUCCESS;
+
+on_error:
+ return status;
+}
+
+/* init streaming with user pointer */
+static pj_status_t vid4lin_stream_init_streaming_user(vid4lin_stream *stream)
+{
+ return PJ_ENOTSUP;
+}
+
+/* init streaming with read() */
+static pj_status_t vid4lin_stream_init_read_write(vid4lin_stream *stream)
+{
+ return PJ_ENOTSUP;
+}
+
+/* API: create stream */
+static pj_status_t vid4lin_factory_create_stream(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm)
+{
+ vid4lin_factory *cf = (vid4lin_factory*)f;
+ pj_pool_t *pool;
+ vid4lin_stream *stream;
+ vid4lin_dev_info *vdi;
+ const vid4lin_fmt_map *fmt_map;
+ const pjmedia_video_format_info *fmt_info;
+ pjmedia_video_format_detail *vfd;
+ pj_status_t status = PJ_SUCCESS;
+
+
+ PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
+ param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
+ param->dir == PJMEDIA_DIR_CAPTURE,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(param->cap_id >= 0 && param->cap_id < cf->dev_count,
+ PJMEDIA_EVID_INVDEV);
+
+ fmt_info = pjmedia_get_video_format_info(NULL, param->fmt.id);
+ if (!fmt_info || (fmt_map=get_v4l2_format_info(param->fmt.id))==NULL)
+ return PJMEDIA_EVID_BADFORMAT;
+
+ vdi = &cf->dev_info[param->cap_id];
+ vfd = pjmedia_format_get_video_format_detail(¶m->fmt, PJ_TRUE);
+
+ /* Create and Initialize stream descriptor */
+ pool = pj_pool_create(cf->pf, vdi->info.name, 512, 512, NULL);
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
+
+ stream = PJ_POOL_ZALLOC_T(pool, vid4lin_stream);
+ pj_memcpy(&stream->param, param, sizeof(*param));
+ stream->pool = pool;
+ pj_memcpy(&stream->vid_cb, cb, sizeof(*cb));
+ strncpy(stream->name, vdi->info.name, sizeof(stream->name));
+ stream->name[sizeof(stream->name)-1] = '\0';
+ stream->user_data = user_data;
+ stream->fd = INVALID_FD;
+
+ stream->fd = v4l2_open(vdi->dev_name, O_RDWR, 0);
+ if (stream->fd < 0)
+ goto on_error;
+
+ status = vid4lin_stream_init_fmt(stream, param, fmt_map->v4l2_fmt_id);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ if (vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)
+ status = vid4lin_stream_init_streaming(stream);
+
+ if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_STREAMING)
+ status = vid4lin_stream_init_streaming_user(stream);
+
+ if (status!=PJ_SUCCESS && vdi->v4l2_cap.capabilities & V4L2_CAP_READWRITE)
+ status = vid4lin_stream_init_read_write(stream);
+
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(1,(THIS_FILE, "Error: unable to initiate I/O on %s",
+ stream->name));
+ goto on_error;
+ }
+
+ /* Done */
+ stream->base.op = &stream_op;
+ *p_vid_strm = &stream->base;
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (status == PJ_SUCCESS)
+ status = PJ_RETURN_OS_ERROR(errno);
+
+ vid4lin_stream_destroy(&stream->base);
+ return status;
+}
+
+/* API: Get stream info. */
+static pj_status_t vid4lin_stream_get_param(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_param *pi)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+ PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
+
+ pj_memcpy(pi, &strm->param, sizeof(*pi));
+
+ return PJ_SUCCESS;
+}
+
+/* API: get capability */
+static pj_status_t vid4lin_stream_get_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ void *pval)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+ PJ_UNUSED_ARG(strm);
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJMEDIA_EVID_INVCAP;
+// return PJ_SUCCESS;
+ } else {
+ return PJMEDIA_EVID_INVCAP;
+ }
+}
+
+/* API: set capability */
+static pj_status_t vid4lin_stream_set_cap(pjmedia_vid_dev_stream *s,
+ pjmedia_vid_dev_cap cap,
+ const void *pval)
+{
+ vid4lin_stream *strm = (vid4lin_stream*)s;
+
+
+ PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
+
+ /*
+ if (cap==PJMEDIA_VID_DEV_CAP_INPUT_SCALE)
+ {
+ return PJ_SUCCESS;
+ }
+ */
+ PJ_UNUSED_ARG(strm);
+ PJ_UNUSED_ARG(cap);
+ PJ_UNUSED_ARG(pval);
+
+ return PJMEDIA_EVID_INVCAP;
+}
+
+/* get frame from mmap */
+static pj_status_t vid4lin_stream_get_frame_mmap(vid4lin_stream *stream,
+ pjmedia_frame *frame)
+{
+ struct v4l2_buffer buf;
+ pj_time_val time;
+ pj_status_t status = PJ_SUCCESS;
+ unsigned tmp_idx;
+
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ status = xioctl(stream->fd, VIDIOC_DQBUF, &buf);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ if (frame->size < buf.bytesused) {
+ /* supplied buffer is too small */
+ pj_assert(!"frame buffer is too small for v4l2");
+ status = PJ_ETOOSMALL;
+ goto on_return;
+ }
+
+ time.sec = buf.timestamp.tv_sec;
+ time.msec = buf.timestamp.tv_usec / 1000;
+ PJ_TIME_VAL_SUB(time, stream->start_time);
+
+ frame->type = PJMEDIA_FRAME_TYPE_VIDEO;
+ frame->bit_info = 0;
+ frame->size = buf.bytesused;
+ frame->timestamp.u64 = PJ_UINT64(1) * PJ_TIME_VAL_MSEC(time) *
+ stream->param.clock_rate / PJ_UINT64(1000);
+ pj_memcpy(frame->buf, stream->buffers[buf.index].start, buf.bytesused);
+
+on_return:
+ tmp_idx = buf.index;
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = tmp_idx;
+ xioctl(stream->fd, VIDIOC_QBUF, &buf);
+
+ return status;
+}
+
+/* API: Get frame from stream */
+static pj_status_t vid4lin_stream_get_frame(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+
+ if (stream->io_type == IO_TYPE_MMAP)
+ return vid4lin_stream_get_frame_mmap(stream, frame);
+ else {
+ pj_assert(!"Unsupported i/o type");
+ return PJ_EINVALIDOP;
+ }
+}
+
+/* API: Start stream. */
+static pj_status_t vid4lin_stream_start(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ struct v4l2_buffer buf;
+ enum v4l2_buf_type type;
+ unsigned i;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(stream->fd != -1, PJ_EINVALIDOP);
+
+ PJ_LOG(4, (THIS_FILE, "Starting v4l2 video stream %s", stream->name));
+
+ pj_gettimeofday(&stream->start_time);
+
+ for (i = 0; i < stream->buf_cnt; ++i) {
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+ status = xioctl(stream->fd, VIDIOC_QBUF, &buf);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+ }
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ status = xioctl(stream->fd, VIDIOC_STREAMON, &type);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ return PJ_SUCCESS;
+
+on_error:
+ if (i > 0) {
+ /* Dequeue already enqueued buffers. Can we do this while streaming
+ * is not started?
+ */
+ unsigned n = i;
+ for (i=0; i<n; ++i) {
+ pj_bzero(&buf, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ xioctl(stream->fd, VIDIOC_DQBUF, &buf);
+ }
+ }
+ return status;
+}
+
+/* API: Stop stream. */
+static pj_status_t vid4lin_stream_stop(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ enum v4l2_buf_type type;
+ pj_status_t status;
+
+ if (stream->fd < 0)
+ return PJ_SUCCESS;
+
+ PJ_LOG(4, (THIS_FILE, "Stopping v4l2 video stream %s", stream->name));
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ status = xioctl(stream->fd, VIDIOC_STREAMOFF, &type);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return PJ_SUCCESS;
+}
+
+
+/* API: Destroy stream. */
+static pj_status_t vid4lin_stream_destroy(pjmedia_vid_dev_stream *strm)
+{
+ vid4lin_stream *stream = (vid4lin_stream*)strm;
+ unsigned i;
+
+ PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
+
+ vid4lin_stream_stop(strm);
+
+ PJ_LOG(4, (THIS_FILE, "Destroying v4l2 video stream %s", stream->name));
+
+ for (i=0; i<stream->buf_cnt; ++i) {
+ if (stream->buffers[i].start != MAP_FAILED) {
+ v4l2_munmap(stream->buffers[i].start, stream->buffers[i].length);
+ stream->buffers[i].start = MAP_FAILED;
+ }
+ }
+
+ if (stream->fd >= 0) {
+ v4l2_close(stream->fd);
+ stream->fd = -1;
+ }
+ pj_pool_release(stream->pool);
+
+ return PJ_SUCCESS;
+}
+
+#endif /* PJMEDIA_VIDEO_DEV_HAS_V4L2 */
diff --git a/jni/pjproject-android/.svn/pristine/25/2586232dac33421a5f2c81cca0eb2933c592ba50.svn-base b/jni/pjproject-android/.svn/pristine/25/2586232dac33421a5f2c81cca0eb2933c592ba50.svn-base
new file mode 100644
index 0000000..9bb760b
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/2586232dac33421a5f2c81cca0eb2933c592ba50.svn-base
@@ -0,0 +1,147 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_TRANSPORT_LOOP_H__
+#define __PJSIP_TRANSPORT_LOOP_H__
+
+
+/**
+ * @file sip_transport_loop.h
+ * @brief
+ * Loopback transport (for debugging)
+ */
+
+
+#include <pjsip/sip_transport.h>
+
+/**
+ * @defgroup PJSIP_TRANSPORT_LOOP Loop Transport
+ * @ingroup PJSIP_TRANSPORT
+ * @brief Loopback transport (for testing purposes).
+ * @{
+ * The loopback transport simply bounce back outgoing messages as
+ * incoming messages. This feature is used mostly during automated
+ * testing, to provide controlled behavior.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Create and start datagram loop transport.
+ *
+ * @param endpt The endpoint instance.
+ * @param transport Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,
+ pjsip_transport **transport);
+
+
+/**
+ * Enable/disable flag to discard any packets sent using the specified
+ * loop transport.
+ *
+ * @param tp The loop transport.
+ * @param discard If non-zero, any outgoing packets will be discarded.
+ * @param prev_value Optional argument to receive previous value of
+ * the discard flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_discard( pjsip_transport *tp,
+ pj_bool_t discard,
+ pj_bool_t *prev_value );
+
+
+/**
+ * Enable/disable flag to simulate network error. When this flag is set,
+ * outgoing transmission will return either immediate error or error via
+ * callback. If error is to be notified via callback, then the notification
+ * will occur after some delay, which is controlled by #pjsip_loop_set_delay().
+ *
+ * @param tp The loop transport.
+ * @param fail_flag If set to 1, the transport will return fail to deliver
+ * the message. If delay is zero, failure will occur
+ * immediately; otherwise it will be reported in callback.
+ * If set to zero, the transport will successfully deliver
+ * the packet.
+ * @param prev_value Optional argument to receive previous value of
+ * the failure flag.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_failure( pjsip_transport *tp,
+ int fail_flag,
+ int *prev_value );
+
+
+/**
+ * Set delay (in miliseconds) before packet is received by the other end
+ * of the loop transport. This will also
+ * control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_recv_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set delay (in miliseconds) before send notification is delivered to sender.
+ * This will also control the delay for error notification callback.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ * @param prev_value Optional argument to receive previous value of the
+ * delay.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_send_callback_delay( pjsip_transport *tp,
+ unsigned delay,
+ unsigned *prev_value);
+
+
+/**
+ * Set both receive and send notification delay.
+ *
+ * @param tp The loop transport.
+ * @param delay Delay, in miliseconds.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_loop_set_delay( pjsip_transport *tp,
+ unsigned delay );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_TRANSPORT_LOOP_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/25/25a47d060db4aac66812983663f5e09036acca9b.svn-base b/jni/pjproject-android/.svn/pristine/25/25a47d060db4aac66812983663f5e09036acca9b.svn-base
new file mode 100644
index 0000000..b8d8126
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/25a47d060db4aac66812983663f5e09036acca9b.svn-base
@@ -0,0 +1,208 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 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 __PJSIP_XFER_H__
+#define __PJSIP_XFER_H__
+
+
+
+/**
+ * @file sip_xfer.h
+ * @brief SIP Transfer (REFER, RFC 3515)
+ */
+#include <pjsip-simple/evsub.h>
+#include <pjsip/sip_msg.h>
+
+/**
+ * @defgroup PJSUA_XFER SIP REFER (RFC 3515) for Call Transfer etc.
+ * @ingroup PJSIP_HIGH_UA
+ * @brief SIP REFER dialog usage (call transfer, etc.)
+ * @{
+ *
+ * This describes a generic handling of SIP REFER request. The SIP REFER
+ * request is described in RFC 3515, and commonly used to perform call
+ * transfer functionality. Other types of SIP REFER usages are described
+ * in draft-worley-sip-many-refers-00 draft, for example:
+ * - Remote Dial: where UAC sends REFER to instruct REFER recipient to
+ * initiate an INVITE session to some target.
+ *
+ * A REFER request can be sent inside or outside existing dialog context,
+ * although for call transfer case, it is more common to send REFER inside
+ * existing INVITE session context. PJSIP supports both sending REFER request
+ * inside or outside dialog context.
+ *
+ * The REFER framework uses @ref PJSIP_EVENT_NOT to manage the event
+ * subscription created by the REFER request. Because of this, application
+ * must link with <b>pjsip-ua</b> AND <b>pjsip-simple</b> static libraries
+ * to use REFER functionality.
+ *
+ * Reference:
+ * - <A HREF="http://www.ietf.org/rfc/rfc3515.txt">RFC 3515: The Session
+ * Initiation Protocol (SIP) Refer Method</A>
+ * - @ref PJSIP_EVENT_NOT
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/** Declaration for REFER method constant. */
+PJ_DECL_DATA(const pjsip_method) pjsip_refer_method;
+
+/** Get REFER method constant */
+PJ_DECL(const pjsip_method*) pjsip_get_refer_method(void);
+
+
+/**
+ * Initialize the REFER subsystem.
+ * This currently does very little (only register REFER as supported method).
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt);
+
+
+
+/**
+ * Create transferer (sender of REFER request).
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_evsub **p_evsub );
+
+
+/**
+ * Create transferee (receiver of REFER request).
+ *
+ * @param dlg The underlying dialog to use.
+ * @param user_cb Pointer to callbacks to receive presence subscription
+ * events.
+ * @param rdata The incoming SUBSCRIBE request that creates the event
+ * subscription.
+ * @param p_evsub Pointer to receive the presence subscription
+ * session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,
+ const pjsip_evsub_user *user_cb,
+ pjsip_rx_data *rdata,
+ pjsip_evsub **p_evsub );
+
+/**
+ * Call this function to create request to initiate REFER subscription,
+ * to refresh subscription, or to unsubscribe. For request other than
+ * the initial REFER request, "refer_to_uri" argument may be NULL.
+ *
+ * @param sub Client subscription instance.
+ * @param refer_to_uri URI to be put to the Refer-To header. This argument
+ * may be NULL for subsequent REFER requests.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,
+ const pj_str_t *refer_to_uri,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Accept the incoming REFER request by sending 2xx response.
+ *
+ * @param sub Server subscription instance.
+ * @param rdata The incoming subscription request message.
+ * @param st_code Status code, which MUST be 2xx.
+ * @param hdr_list Optional list of headers to be added in the response.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,
+ pjsip_rx_data *rdata,
+ int st_code,
+ const pjsip_hdr *hdr_list );
+
+
+/**
+ * For notifier, create NOTIFY request to subscriber, and set the state
+ * of the subscription.
+ *
+ * @param sub The server subscription (notifier) instance.
+ * @param state New state to set.
+ * @param xfer_st_code The call status code to be reported with the NOTIFY
+ * request.
+ * @param xfer_st_text Optional call status text to be reported with the
+ * NOTIFY request. If the value is NULL, default
+ * status text will be used.
+ * @param p_tdata Pointer to receive the request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,
+ pjsip_evsub_state state,
+ int xfer_st_code,
+ const pj_str_t *xfer_st_text,
+ pjsip_tx_data **p_tdata);
+
+
+/**
+ * Create NOTIFY request to reflect current subscription status. Application
+ * can only call this function after it has sent NOTIFY before.
+ * This will also re-send the last "message/sipfrag" body that was sent
+ * in the previous NOTIFY.
+ *
+ * @param sub Server subscription object.
+ * @param p_tdata Pointer to receive request.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,
+ pjsip_tx_data **p_tdata );
+
+
+
+/**
+ * Send request message that was previously created with initiate(), notify(),
+ * or current_notify(). Application may also send request created with other
+ * functions, e.g. authentication. But the request MUST be either request
+ * that creates/refresh subscription or NOTIFY request.
+ *
+ *
+ * @param sub The event subscription object.
+ * @param tdata Request message to be send.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,
+ pjsip_tx_data *tdata);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJSIP_XFER_H__ */
+
diff --git a/jni/pjproject-android/.svn/pristine/25/25fad9456e3f97ff2f27cf0320d7b2b941c3d26d.svn-base b/jni/pjproject-android/.svn/pristine/25/25fad9456e3f97ff2f27cf0320d7b2b941c3d26d.svn-base
new file mode 100644
index 0000000..1eeee93
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/25/25fad9456e3f97ff2f27cf0320d7b2b941c3d26d.svn-base
@@ -0,0 +1,211 @@
+
+ /******************************************************************
+
+ iLBC Speech Coder ANSI-C Source Code
+
+ StateSearchW.c
+
+ Copyright (C) The Internet Society (2004).
+ All Rights Reserved.
+
+ ******************************************************************/
+
+ #include <math.h>
+ #include <string.h>
+
+ #include "iLBC_define.h"
+ #include "constants.h"
+ #include "filter.h"
+ #include "helpfun.h"
+
+ /*----------------------------------------------------------------*
+ * predictive noise shaping encoding of scaled start state
+ * (subrutine for StateSearchW)
+ *---------------------------------------------------------------*/
+
+ void AbsQuantW(
+ iLBC_Enc_Inst_t *iLBCenc_inst,
+ /* (i) Encoder instance */
+ float *in, /* (i) vector to encode */
+ float *syntDenum, /* (i) denominator of synthesis filter */
+ float *weightDenum, /* (i) denominator of weighting filter */
+ int *out, /* (o) vector of quantizer indexes */
+ int len, /* (i) length of vector to encode and
+ vector of quantizer indexes */
+ int state_first /* (i) position of start state in the
+ 80 vec */
+ ){
+ float *syntOut;
+ float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
+ float toQ, xq;
+ int n;
+ int index;
+
+ /* initialization of buffer for filtering */
+
+ memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
+
+
+
+
+
+
+ /* initialization of pointer for filtering */
+
+ syntOut = &syntOutBuf[LPC_FILTERORDER];
+
+ /* synthesis and weighting filters on input */
+
+ if (state_first) {
+ AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER);
+ } else {
+ AllPoleFilter (in, weightDenum,
+ iLBCenc_inst->state_short_len-SUBL,
+ LPC_FILTERORDER);
+ }
+
+ /* encoding loop */
+
+ for (n=0; n<len; n++) {
+
+ /* time update of filter coefficients */
+
+ if ((state_first)&&(n==SUBL)){
+ syntDenum += (LPC_FILTERORDER+1);
+ weightDenum += (LPC_FILTERORDER+1);
+
+ /* synthesis and weighting filters on input */
+ AllPoleFilter (&in[n], weightDenum, len-n,
+ LPC_FILTERORDER);
+
+ } else if ((state_first==0)&&
+ (n==(iLBCenc_inst->state_short_len-SUBL))) {
+ syntDenum += (LPC_FILTERORDER+1);
+ weightDenum += (LPC_FILTERORDER+1);
+
+ /* synthesis and weighting filters on input */
+ AllPoleFilter (&in[n], weightDenum, len-n,
+ LPC_FILTERORDER);
+
+ }
+
+ /* prediction of synthesized and weighted input */
+
+ syntOut[n] = 0.0;
+ AllPoleFilter (&syntOut[n], weightDenum, 1,
+ LPC_FILTERORDER);
+
+ /* quantization */
+
+ toQ = in[n]-syntOut[n];
+
+
+
+
+
+ sort_sq(&xq, &index, toQ, state_sq3Tbl, 8);
+ out[n]=index;
+ syntOut[n] = state_sq3Tbl[out[n]];
+
+ /* update of the prediction filter */
+
+ AllPoleFilter(&syntOut[n], weightDenum, 1,
+ LPC_FILTERORDER);
+ }
+ }
+
+ /*----------------------------------------------------------------*
+ * encoding of start state
+ *---------------------------------------------------------------*/
+
+ void StateSearchW(
+ iLBC_Enc_Inst_t *iLBCenc_inst,
+ /* (i) Encoder instance */
+ float *residual,/* (i) target residual vector */
+ float *syntDenum, /* (i) lpc synthesis filter */
+ float *weightDenum, /* (i) weighting filter denuminator */
+ int *idxForMax, /* (o) quantizer index for maximum
+ amplitude */
+ int *idxVec, /* (o) vector of quantization indexes */
+ int len, /* (i) length of all vectors */
+ int state_first /* (i) position of start state in the
+ 80 vec */
+ ){
+ float dtmp, maxVal;
+ float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS];
+ float *tmp, numerator[1+LPC_FILTERORDER];
+ float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout;
+ int k;
+ float qmax, scal;
+
+ /* initialization of buffers and filter coefficients */
+
+ memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
+ memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
+ for (k=0; k<LPC_FILTERORDER; k++) {
+ numerator[k]=syntDenum[LPC_FILTERORDER-k];
+ }
+ numerator[LPC_FILTERORDER]=syntDenum[0];
+ tmp = &tmpbuf[LPC_FILTERORDER];
+ fout = &foutbuf[LPC_FILTERORDER];
+
+ /* circular convolution with the all-pass filter */
+
+
+
+
+
+
+ memcpy(tmp, residual, len*sizeof(float));
+ memset(tmp+len, 0, len*sizeof(float));
+ ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
+ LPC_FILTERORDER, fout);
+ for (k=0; k<len; k++) {
+ fout[k] += fout[k+len];
+ }
+
+ /* identification of the maximum amplitude value */
+
+ maxVal = fout[0];
+ for (k=1; k<len; k++) {
+
+ if (fout[k]*fout[k] > maxVal*maxVal){
+ maxVal = fout[k];
+ }
+ }
+ maxVal=(float)fabs(maxVal);
+
+ /* encoding of the maximum amplitude value */
+
+ if (maxVal < 10.0) {
+ maxVal = 10.0;
+ }
+ maxVal = (float)log10(maxVal);
+ sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);
+
+ /* decoding of the maximum amplitude representation value,
+ and corresponding scaling of start state */
+
+ maxVal=state_frgqTbl[*idxForMax];
+ qmax = (float)pow(10,maxVal);
+ scal = (float)(4.5)/qmax;
+ for (k=0; k<len; k++){
+ fout[k] *= scal;
+ }
+
+ /* predictive noise shaping encoding of scaled start state */
+
+ AbsQuantW(iLBCenc_inst, fout,syntDenum,
+ weightDenum,idxVec, len, state_first);
+ }
+
+
+
+
+
+
+
+
+
+
+